Monday, February 7, 2011

Refactoring the code out of the T4 template

T4 templates have been a great way to generate code in visual studio, and at SyneITY we use code generation where developers find themselves repeating things. T4 has helped us achieve much better productivity. Also special thanks to Tangible for their Syntax Highlighting without which T4 wouldn’t have been a piece of cake.

The Reason for Refactoring:

Though T4 in its own was wonderful however while writing our T4 templates we came across a few problems namely:

  • The only way to use code within T4 was using the functions and there was no way to define classes within the T4 making it difficult to write complex T4 templates.
  • Reusability of T4 templates was very difficult.
  • We need to write all the boiler plate code in each template. eg. if we needed to fetch something from the database, we had to write everything from creating the connection string to executing the command.

The Solution:

If we could refactor out the code we write within T4 templates to classes and put them in a separate assembly, and refer them in the T4 template then these issue would be solved. Let us check how this can be implemented using an example.

Sample Scenario:

Consider the following scenario:

  • You are given information regarding Entities .
  • This information can be either in an xml file, in a sql database
  • You have to generate classes for each entityimage

 

 

 

 

Fig 1: Our requirement in pictures.

will implement this in the normal way first and then refactor it.

  1. Solution 1 - Normal Way

In the template we do the following:

  • Build the full name of the xml file
  • Read the xml text from the xml file using the xml file name
  • Parse the xml using “Linq to xml”
  • Use linq to loop through the xml elements and build the object structure in memory
  • use the object structure to generate the code.

    image

Problems of Solution 1

In the template we had to do all things from building the file name, to loading the xml, parsing the xml and building the object structure from it, resulting in a lot of code within the template. and all of this for just a small xml, what would be the case for more complex scenarios.

Solution 2 – Moving the logic out.

We moved out the entire logic out of the T4 template into a seperate dll with name “TemplateLogic”. Now where do we put the dll so that we can reference it in the T4 template? The options are :

  1. Put any where and reference it using the fully qualified path of the dll.
  2. Put it in the same location as the T4 template
  3. Modify the project references path in the project properties.
  4. Install it in the GAC.

I opted for the 4th option of installing it in the  GAC, since i would require this dll to be shared across applications and programmers.

So i registered the dll into the GAC. For more information on registering a dll into the GAC Visit my blog here.

Now to reference this dll we add the following to the T4 template to refer this dll

<#@ Assembly Name="TemplateLogic" #>

The resulting template will be as below:

image

Conclusion:

The difference between the two templates is obvious, and we can modify the template without any fear of modifying any code. Hope this post becomes useful for someone.

Downloads:

You can download the sample solution here.

References:

Syntax Highlighting using Tangible http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html
Understanding referencing assemblies in T4 http://www.olegsych.com/2008/02/t4-assembly-directive/

No comments:

Post a Comment