A while back I blogged about customizing the SQL that is generated by Code First Migrations. In this post I’m going to step back up the pipeline a bit and look at customizing the code that gets scaffolded when you call Add-Migration.
When we built Code First Migrations we made an effort to make everything pluggable. For example, the component that scaffolds the code of a migration based on the changes detected in your model should be replaceable with your own implementation.
We also tried to factor our implementations in such a way that it was easy to override small parts of the default behavior without writing a lot of code. For example, if you want to add a small section to the start of each migration that is scaffolded, you shouldn’t have to implement a complete code generator.
Creating a Custom Code Generator
Let’s say we want to add a couple of comments to the top of each migration that records who generated the migration and when they generated it. We can derive from the default code generator and override the method that generates the start of the class. In this example I’m writing the desired information to the IndentedTextWriter and then calling the base implementation to write the remainder of the default code.
using System; using System.Data.Entity.Migrations.Design; using System.Data.Entity.Migrations.Utilities; public class MyCodeGenerator : CSharpMigrationCodeGenerator { protected override void WriteClassStart( string @namespace, string className, IndentedTextWriter writer, string @base, bool designer = false, System.Collections.Generic.IEnumerable namespaces = null) { writer.WriteLine("// Generated Time: {0}", DateTime.Now); writer.WriteLine("// Generated By: {0}", Environment.UserName); writer.WriteLine(); base.WriteClassStart(@namespace, className, writer, @base, designer, namespaces); } }
The easiest way to see what methods you can override, and what they do, is to look at the source code for the default implementation. That’s very easy because EF is open source and you can browse the source online. Under src\EntityFramework\Migrations\Design you’ll find CSharpMigrationCodeGenerator.cs and VisualBasicMigrationCodeGenerator.cs.
Registering a Custom Code Generator
Now that we’ve built a custom code generator we can register it in the constructor of our migration configuration class.
public Configuration() { AutomaticMigrationsEnabled = false; CodeGenerator = new MyCodeGenerator(); }
Now if we run the Add-Migration command we’ll see the information is added to the top of the scaffolded code.
// Generated Time: 11/30/2012 2:35:08 PM // Generated By: rowmil namespace ConsoleApplication1.Migrations { using System; using System.Data.Entity.Migrations; public partial class AddRating : DbMigration { public override void Up() { AddColumn("dbo.Blogs", "Rating", c => c.Int(nullable: false)); } public override void Down() { DropColumn("dbo.Blogs", "Rating"); } } }