Monday, 7 March 2016

Customize reverse engineer code first EF6.x– EFPowerTool enhancement

Do you know you can customize the code generation for EF 6.x code first? If you are surprised then you can read out a start with guide here about the EF power tool to get more insights of code generation process.

What can I customize using EF power tools?

You can customize the class names, attributes, methods anything related to code that lies in your database context, entity or mapping classes.

Why would I need such customization?

Sometimes you may want to prefix/suffix the names of entities according to your requirement or may be putting some custom attributes etc.

What this blog is about?

This blog will not cover how to use the EF power tools. I already mentioned it in the start of the post about the tutorial where you can learn about it.
In this blog we’ll talk about some enhancements which would make the tool a bit more flexible for generating classes with directory hierarchy based on namespace. Well this sentence went bit too long. So I’ll start step by step understanding the issue and what could be the proposed fix:

I have encountered couple of questions in forums that the EF code templates are only generating code in a particular designated directory. Below are the files which you would get after installing the EFPowerTool.

Now, if you have already existing Code first in the project and you want to use the EF code template to customize them. You’ll end up having below directory hierarchy after code generation. Well you have to change the namespaces and directory hierarchy according to your existing structure of code first classes.

After doing a bit of research in the EF6.x source code, Found that the Model and Mapping directories including the namespaces are hardcoded in the code. To fix this problem I had to understand the whole process of code generation. So after few hours of research I figured out that the Custom code template files have access the EfTextTemplateHost object via Host property.

Also I found below properties in the EfTextTemplateHost object which can be used to change the namespace for code generation.

        public string Namespace { get; set; }

        public string ModelsNamespace { get; set; }

        public string MappingNamespace { get; set; }

So this properties can be utilized to change the existing generation behavior for placing the classes in hierarchy w.r.t namespaces. So I added a new utility class which can sync the namespace with directory hierarchy. (sourcecode here). It might not be covering all the cases because I wrote some tests to ensure existing functionality is not broken. And to verify if the new required changes are working. Below are the files which were affected for this change:

src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Context.tt

src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Entity.tt

src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Mapping.tt

src/PowerTools/Handlers/ReverseEngineerCodeFirstHandler.cs

src/PowerTools/Utilities/ProjectFilesPathGenUtility.cs

The all .tt code template files have sample added in the comments how you can define the namespace to get the structure generated in desired hierarchy.

                /*

                                   Customize the file generations according to namespace hierarchy

                                   efHost.Namespace = "DataAccess";

                                   efHost.ModelsNamespace = "DataAccess.Models";

                                   efHost.MappingNamespace = "DataAccess.Mappings";

                */

This settings will generated below directory hierarchy.

Well this would solve problem of few askers like here and here. I have submitted a PR to EF team for EF6.x repository. While waiting for feedback I have created an experimental branch of EFPowerTool on github. You can download and install the extension installation file from here (Right click and choose save as…). Those who are interested in making more enhancement of want to review this changes feel free to review/test. Raise any issues on github I’ll try to work on it with you.

Hope we can make the beta release to bits of RC for the extension.