Customizing Code Generation

Easy code customization was a design goal with this tool. There are two levels, and you can choose which one is best depending on your needs.

Partial Classes

Easiest is to simply extend the custom code by implementing partial classes. Use these to add any methods to the generated classes you need; they’ll be untouched if the model is later regenerated.

The generated code also creates partial methods at locations that have historically shown themselves to be common places for extension. Those are:

Note that, if you typically override SaveChanges to do custom processing, that override is already generated for you and does some work. If this doesn’t suit you, you can always put a copy of the appropriate .ttinclude file into your project and remove that bit.

Remember that partial methods, if not implemented, don’t generate IL and therefore don’t have any performance overhead, so they’re an excellent means of optional behavior injection.

Replacing the T4 Templates

You can easily replace the T4 templates installed with the extension either globally or on a project-by-project basis. The trick (thanks Microsoft!) is finding them.

The designer is installed in the all-user extension location, typically

C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions

(Note that my installation has the Enterprise folder in its path; that’s because I happen to be using Visual Studio Enterprise. If you don’t, you’ll have a slightly different path.)

The fun begins when you get to that Extensions directory … each extension is installed in a unique folder with a random (pseudo-random?) name. The easiest thing to do is to hunt for EFDesigner.ttinclude starting in the Extensions folder.

When you find it, you’ll see five .ttinclude files there:

FileDescription
EFDesigner.ttincludeCode useful to all flavors of Entity Framework. Also contains code to write the entities and enumerations.
EF6Designer.ttincludeWrites the EF6 DbContext, database initializer and migration configuration. Any code that only works with EF6 is defined here.
EFCoreDesigner.ttincludeSame as above, but for EF Core v2 instead.
MultipleOutputHelper.ttincludeCode to create more than one output file, since T4 usually doesn't do that. You probably won't mess with this.
VSIntegration.ttincludeCode to talk to Visual Studio so we can add project items, etc. You probably won't mess with this either.

Decide what you want to replace and copy the file into the folder containing your .efmodel and .tt files. Modify at will; the templating engine will find your local copy before it looks anywhere else. That will customize the code generation for that project. If you want to globally change how code is generated, edit the .ttinclude files directly in the install directory. Be aware, though, that updates will overwrite those files, and you’ll have to go through the excercise of editing them whenever you install a newer version of the designer. (If you feel strongly that you have a really good improvement, you can always submit it as a pull request!)

For code generation from the T4, the flow of events starts at the [Model Name].tt file in your project. Its template directives tell it to include the five templates listed above and then, based on the Entity Framework type specified, call one of two entry points.

You’ll notice that these aren’t your standard T4 templates, where the bulk of the file is text to be output. Rather, they’re like scripting libraries. That’s on purpose – a design goal was to allow the generation to be customizable but, at the same time, understandable to the average programmer. A group of function calls is easier to read, IMHO, than your everyday T4 template, so that’s what we have.

The templating engine works through the model, pulling together all the code in memory. It isn’t until the call to manager.Process(true) at the end that the files are generated. So any customizations to the process should come before that call.

Customizing Designer Behavior

Beginning with v1.1, the designer can be extended using Microsoft’s Managed Extensibility Framework so that you can modify not just the output generating via the T4 templates, but the designer behavior itself. Microsoft has a nice writeup on how to write MEF extensions for domain-specific languages that applies not only to the designer but any Visual Studio DSL … please see that documentation for details.

Next Step

Contributing