Advertisment

Autogenerate Code Using T4 in VS 2010

author-image
PCQ Bureau
New Update

If you look at the work that a normal developer does most of the time, it's a

fairly repetitive job wherein he writes code for doing a particular module which

is similar to everything else that is done with small differences being say, the

fields that need to be displayed/updated to a different table in a different

database. There are many other things that are similar as well.

Advertisment

However, there is a way to not just automate this work so that the developer

has to only fill in the requirements and the code gets generated, but also

ensure that the code is up to standards as defined by policy. This can make the

architect's and project manager's, not to mention the developer's life also much

better. There is a technology in the .NET world that allows you to do this

called T4.

T4 is an abbreviation for Text Template Transformation Toolkit. This is way

of writing a 'template' that can generate code from a set of rules, other code,

or data input. You can write a template that can be used multiple times with a

slight change in input which will output code for different scenarios. Fairly

complex scenarios are possible by using this. Let's start with some simple

examples and then move on to some more complex ones to see how they work.

Direct Hit!

Applies To: Web Developers



USP: Learn how to automate developer's job using T4


Primary Link:
http://bit.ly/d3vVy1




Search Engine Keywords: T4, visual studio

Advertisment

First of all, fire up Visual Studio 2010 (or Visual Studio 2008 with the free

T4 Toolbox  installed). Note that in VS2008, you will not see an item type in

the new item list and will need to create a text file yourself. In VS2010,

simply create an 'Empty Project' and then add a new item of type 'Text

Template'. This will create a new file with the extension of '.TT'. When the

file opens in VS, you will see the following lines:

<#@ template debug="false" hostspecific="false"

language="C#" #>



<#@ output extension=".txt" #>

There are a couple of things to note here. The language attribute in the

first line specifies that language that is going to be used for creating the

template — not the language that is the output. The extension attribute in the

second line specifies the type of file that is going to be generated. Expand the

.TT file you created in Solution Explorer and you'll see a .TXT file with the

same name. Now change the value in the extension to say '.cs' and it will change

the file as well. Change the .TT file to the following:

Advertisment

<#@ template debug="false" hostspecific="false"

language="C#" #>



<#@ output extension=".cs" #>


using System;


namespace Hello


{


class Program


{


public void Main()


{ Console.WriteLine("Hello World"); }}}






As soon as you save the file, open up the associated .CS

file. You should see the entire code (other than the T4 directives at the top)

generated for you. Congrats, you've just auto-generated your first piece of

code.

Text Template item type in VS 2010
Advertisment

However, this is not really impressive right now. You've

actually written more than what the code actually is. But think of a case where

you might need to write this exact same code out, but just change the message

that is shown. For this, you now need to start writing T4 code itself to allow

the template to accept parameters and use them in the code generation.

Modify the code above by changing the Writeline line and

adding the following:

{ Console.WriteLine("<#= this.Message

#>");}}}



<#+


string Message = "Hi There";


#>

Advertisment

When you save this file and open the .CS one, you will see

that the message has indeed changed. The '<#=' and the '<#+' signs are some T4

directives to tell the T4 compiler what needs to be done. Now by simply changing

the value in the Message variable, you can output different code files each

time.

An autogenerated ASP.NET WebForm using a

T4 template

You can also include other code files to your own. For

instance, you might want to generate this file after some other processing. So

create a new .TT file, say MyTest1.tt and have the following within it:

Advertisment

<#@ template debug="false"

hostspecific="false" language="C#" #>



<#@ output extension=".cs" #>


<#


this.Message = "Hallo Welt!";


#>


<#@ include file="HelloWorld.tt" #>



Open the MyTest1.cs file, and you'll find a German version

of the 'Hello World' message. You can of course go ahead and generate a bunch of

code more complex than this of course. As an example, let's take a look at some

templates that automatically generate ASP.NET files - both ASPX and ASPX.CS  -

for working with a database table. For code generation, the developer simply

needs to change an XML file that defines the table and the fields.

A number of T4 template files are needed in this case:

Advertisment

1.WebFormFields.tt: Generates the frontend ASPX and HTML

code

2.CodeBehindFields.tt: Generates backend database

connectivity code (for this article only displays field name)

3.SaveOutput.tt: Saves the ASPX and ASPX.cs file in the

current directory

4.BuildPagesFromXML.tt: Reads the XML file for fields and

then uses the other T4 files to generate

The code in each (abbreviated) looks like this:

WebFormFields.tt

<#+ void GenerateASPXField(string

FName, string Type, string Choices) { #>



:


<#+ switch (Type) {


case "Text": #>







<#+ break; case "List": #>





<#+ string<> items = Choices.Split(';'); for (int i = 0; i < items.Length; i++)
{ #>



 <#= items #>


<#+ } #>








<#+ break; default: break; }} #>




This code defines a T4 function that simply outputs a

textbox and a dropdownlist for fields defined as such in an XML file.

CodeBehindFields.tt



<#+ void GenerateCBFieldSave(string FName, string Type, string Choices) {


switch (Type) {


case "Text": #>


Response.Write("Field <#= FName #>; Value= " + txt<#= FName #>.Text);


<#+ break; case "List": #>


Response.Write("Field <#= FName #>; Value= " + ddl<#= FName #>.SelectedValue);


<#+ break; default: break; } } #>





Another autogenerated Webform using the

same T4 template

This defines a T4 function that simply outputs the

fieldname and associated value.

SaveOutput.tt



<#@ template language="C#" hostspecific="true" #>


<#@ import namespace="System.IO" #>


<#+


void SaveOutput(string outputFileName)


{


string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);




string outputFilePath =

Path.Combine(templateDirectory, outputFileName);



File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString());

this.GenerationEnvironment.Remove(0,

this.GenerationEnvironment.Length);



}


#>

This defines a function that saves both the ASPX and

ASPX.cs files when called.

BuildPagesFromXML.tt

This code will need to generate the standard ASP.NET header

and footer for both files and also the generated code by including the files

above. The main code for generating the fields looks like this:

foreach (XmlNode node in

doc.SelectNodes("/Fields/Field"))



{


FieldName = node.Attributes<"Name">.InnerText;


Type = node.Attributes<"Type">.InnerText;


switch (Type)


{


case "Text":


GenerateASPXField(FieldName, Type, "");


break;


case "List":


GenerateASPXField(FieldName, Type, node.Attributes<"Choices">.InnerText);


break;


}


}


SaveOutput(WebFormName + ".aspx");


foreach (XmlNode node in doc.SelectNodes("/Fields/Field"))


{


FieldName = node.Attributes<"Name">.InnerText;


Type = node.Attributes<"Type">.InnerText;


switch (Type)


{


case "Text":


GenerateCBFieldSave(FieldName, Type, "");


break;


case "List":


GenerateCBFieldSave(FieldName, Type, node.Attributes<"Choices">.InnerText);


break;


}


}


SaveOutput(WebFormName + ".aspx.cs");



























The input XML file looks like this:

?>























As you change the form name and the fields, a new Name.aspx

and Name.aspx.cs files with the correct front and backend code will be generated

in the directory. As the entire set of templates was too large for this article,

I'll be uploading the solution to the PCQ Forums where you can pick it up.

T4 templates are powerful ways of automating and

standardizing code generated in your company's projects. You can use this to

enhance productivity as well as let developers work on better value additions to

the project that doing the same repetitive job everyday.

Advertisment