When VS 2010 ships it will include some significant improvements to our code generation story for the Entity Framework. The basic idea is to make use of T4 templates for code generation and ship strong integration into the Entity Framework Designer to make the experience of customizing those templates as seamless as possible.
Below Sanjay from our Tools team outlines what will be possible once VS 2010 is released.
Customize the code generated by the Entity Designer with T4 templates
In Visual Studio 2008 SP1, the ADO.NET Entity Designer generates classes from the CSDL portion of the EDMX file using the EntityClassGenerator APIs. Numerous customers have asked us how to customize the code generation for a variety of scenarios including:
- Make the generated ObjectContext internal
- Make the generated ObjectContext and Entity classes implement a user-defined interface
- Add user-defined CLR attributes to generated ObjectContext and generated Entity classes
- Influence generated classes based on structural annotations in CSDL
- Generate the ObjectContext and Entity classes into separate files
- Generate “proxy classes” for the generated classes
- Partially or fully change how classes are generated, maybe even generate additional (non code) artifacts in the project
- Completely replace entity framework code generation with custom code
- Generate POCO classes from the model to use as a starting point in my applications
- Generate self-tracking entity classes
- · …
While the SingleFileGenerator techniques described here enable some of these scenarios these techniques are generally difficult to implement and install or are tricky to debug and customize.
In Visual Studio 2010, we plan to give customers the ability to use T4 templates to generate their classes, and are also planning deep integration with the Entity Designer and Visual Studio to provide a great end-to-end experience.
The example below customizes code generation to make the generated classes implement a user-defined interface (e.g. IValidate).
- User has installed Visual Studio 2010
- User is familiar with customizing T4 templates
- User has a C# or a VB console project that targets FX4.0 with an EDMX file in the project
- User: opens EDMX file in the Entity Designer. Note that the generated classes are in a child file of the EDMX file (i.e. in Northwind.Designer.cs)
- User: right-clicks on an empty area of the designer surface and chooses “Add New Artifact Generation Item…” from the context menu.
- Visual Studio: displays the standard “Add New Item” dialog and shows a filtered list of items for the user to select from. As expected, the “Add New Item” dialog only shows a list of item templates specific to the current project target framework version, project type and language.
- User: selects “ADO.NET EntityObject Generator”, specifies a file name and clicks “Add”
- Visual Studio: checks out the project from Source Control if necessary
- Visual Studio: sets the “Custom Tool” property of the EDMX file to empty, which will cause the existing .designer.cs file to be deleted
- Visual Studio: the VS item template adds a new .tt file to the project in the same project directory as the EDMX file
- Visual Studio: configures the new .tt file to process the selected EDMX file. The EDMX file to process is a replaceable parameter in the .tt file, and VS updates it to point to the selected EDMX file. Thus, the .tt file now knows which EDMX file to generate code for.
[Screenshot of .tt file open in the Clarius T4 Editor Community edition for VS 2008]
- User: double-clicks the .tt file in the project to open it in VS10
- User: edits the .tt file in Visual Studio to make every Entity object implement the IValidate interface
[Screenshot of .tt file open in the Clarius T4 Editor Community edition for VS 2008]
- User: saves and closes .tt file
- Visual Studio: Transforms the .tt file to produce the generated classes as a child file of the .tt file
- User: notes that the generated classes (under the .tt file) implement the IValidate interface as expected
- User: switches to the EDMX file in the designer and makes some changes (e.g. add a new entity)
- User: saves EDMX file
- Visual Studio: Transforms all .tt files in the project that reference the EDMX file. As before, the generated classes are child files of the .tt files
The design affects multiple parts of the Entity Framework and the Entity Designer and the key changes are described below:
Entity Framework Runtime
- We started by creating C# and VB T4 templates to generate classes from CSDL and EDMX files
- Since the T4 engine is installed with Visual Studio and not with the.NET FX runtime, we preprocess the templates as described here and include the compiled code into System.Data.Entity.Design.dll
- We added a new class System.Data.Entity.Design.EntityCodeGenerator (in System.Data.Entity.Design.dll ) that generates code using the preprocessed T4 template
- Finally, we enhanced a few runtime metadata APIs and added extension methods to load and iterate over models a lot easier. Our T4 templates make heavy use of these new methods.
We took the C# and VB T4 templates used by the runtime and changed them to be more “VS friendly” as described below.
- We made the EDMX file name referenced in the T4 templates a replaceable parameter
- We created a wizard (with no GUI) that is launched by Visual Studio when the item is added to the project. The wizard does 2 things:
- updates the EDMX file name referenced in the T4 templates and
- sets the “Custom Tool” property of the EDMX file to empty
- We rolled up the T4 templates (and wizard) into standard C# and VB Visual Studio item template which are installed with VS 2010; this makes them show up in the “Add New Item” dialog in Visual Studio
- We added a new context menu to the designer surface to launch the “Add New Item” dialog and also added code to only show VS item templates whose names start with the prefix ADONETArtifactGenerator_
- Our design ensures that user installed VS item templates in %MyDocuments% as well as the VS item templates we ship in box show up in the “Add…New…Item” dialog (per the template name prefix rule above)
- We added code to the designer that finds all .tt files related to an EDMX file and automatically transform them when the EDMX file is saved.
- Finally, we added a new property called “Process related T4 templates on Save” on the designer surface to let users control whether or not to transform .tt files related to the EDMX file on save.
Multi Targeting considerations
As many of you are aware, VS 2010 allows developers to target FX4.0 as well as FX3.5 (and older runtimes). The T4 templates that we ship in the Visual Studio box generate code that works with the Entity Framework in .NET FX 4.0. This means the VS item templates we ship in the box will not be available for projects that target FX3.5.
However, it is certainly possible (and supported) for users to create new T4 templates (and new VS item templates) that generate code from an EDMX file in projects that target FX3.5 and light up in the same experience. In fact, we might release some new templates ourselves later, on CodeGallery perhaps.
How can 3rd parties plug in?
Since our design is based upon VS item templates that wrap T4 templates, we have opened the door to let 3rd party code generators participate in the end-to-end experience. Our contract is straight forward and easy to implement:
- Create a (C# or VB) T4 template to generate code as you desire. The T4 templates we ship in the box can be invaluable points of reference as you roll your own.
- Make the EDMX reference in your .tt file a replaceable parameter by calling it $edmxInputFile$ like we do in our .tt file.
- Wrap the .tt file in a VS item template. This is pretty easy and well documented on MSDN. You can also use the Export Template wizard included Visual Studio. Also specify additional VS item template settings such as target framework, project type, etc
- Prefix the name of your .vstemplate file with ADONETArtifactGenerator_ if you want your VS item template to show up in the “Add New Item” dialog when it is launched from the context menu in the Entity Designer.
- You can use the wizard we ship in Visual Studio to do parameter replacement in your VS item template by adding the following to your .vstemplate file:
Microsoft.Data.Entity.Design, Version=10.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a
Of course, you can also create your own wizard that does custom processing when the item is added to the project as described here.
- Create a VSCONTENT file and zip up your custom item template & related files into a Visual Studio Content Installer (.vsi) file
- Upload the .vsi file someplace your customers can download it from
- Visual Studio already knows how to install .vsi files and everything you need is already available in Visual Studio.
A few key takeaways:
- This design lets the EF team release new T4 templates outside the usual Visual Studio and .NET FX ship cycles and the experience to consume them is exactly the same.
- There are several excellent resources on the web that describe advanced T4 template scenarios and our design enables them. In fact, we expect users to leverage these resources while creating new T4 templates or customizing the ones we ship. For example, code in a custom T4 template can use the EnvDTE APIs to access the project system and generate outputs to multiple files.
- Over time, we expect to blog about some of these advanced scenarios and also work with MVPs, industry experts and Patterns & Practices to provide guidance to customers in a manner similar to the Guidance Automation Toolkit.
- Custom T4 templates can generate anything you want, not just code. For example, we have an internal prototype of a T4 template that iterates over a model and generates an HTML file with a nicely formatted report of the entities and associations in the model
- VS item templates can add multiple files to your project (more details here). This means your custom item templates can include all kinds of files (e.g. workflow files, multiple T4 files, pre-canned code files, etc). For example, you can easily imagine a 3rd party VS item template that adds 2 .tt files in your project that process the same EDMX file but generate different kinds of outputs.
We hope this gives you an overview of our design and intent of this feature and we would love to hear your comments.
Lead PM, ADO.NET Entity Designer
This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at this post.