Musing around T4 Templates – Part 1

 

In .NET 4.0 the new Entity Framework is heavily wired with T4 capabilities. By the way T4 stands for Text Template Transformation Toolkit. Actually it is nice, that you can benefit from those templates even without the slightest idea about the real T4-Syntax. However sometimes high price has to be paid being ignorant. In this article I will guide you through the basics while creating such template from the scratch, and in my next articles I will show you how to use these freshly elaborated skills while dealing with Entity Framework related problems.

The very first step I recommend is to download an install the tangible T4 Editor, which is a free plug-in for Visual Studio 2010 (or VS 2008). To be honest the package offers a lot more than being a simple T4-Editor. At the end of the day however we will only use it’s T4 editing, intellisense and coloring capabilities.

So I assume the tangible T4 Editor installation went fine, and you could start a new Windows Console Project. Right mouse button on the newly created Project in the Solution explorer and add select new Item. From the list in the dialog box select “General” and chose “Text Template” (Picture 1). Name it like T4Text.tt

Picture 1

Please note, that the tangible T4 Editor added a few more templates as well which you could see while choosing “tangible T4 templates” from the list (Picture 1a). At this time however it is completely save to ignore them all.

Picture 1a 

Next open the newly created text template and check the two lines generated. They are are called T4 Pragma Sections. First of all change on second line the output file’s extension to .cs, as we are going to create some meaningful T4 Template targeting C# language. Note the syntax looks very much like ASP.NET directives with a great number of attributes colored in red. Click on any line and hit the space button on your keyboard which will immediately trigger the tangible T4 Editor’s intellisense offering an additional list of possible attributes (Picture 2).

Picture 2

Add now in  a pretty clear C# syntax the declaration in Code 1 directly beneath the two T4 Pragma Sections (introductory declarations) and let’s compile the project. Not surprisingly we have got a a T4Text.cs file generated containing a public class and a public void method writing a familiar text into the console window.

namespace ConsoleAppT4 

    public class Stuff 
    { 
        public Stuff() 
        { 
        } 
         
        public void DoStuff() 
        { 
            Console.WriteLine("Hello World I’m doing stuff");
        } 
    } 
}

Code 1
As the Console class is unknown in the generated output file, we have to insert an additional using System; statement before the class declaration. Additionally let insert informative comments about the magic we are dealing with. The result thereafter looks like in Code 2 depicted:
 
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs"  #>
// ——————————————
// <auto-generated>
//         This code was auto-generated today
// <auto-generated>
// —————————————–

using System;
namespace ConsoleAppT4 

    public class Stuff 
    { 
        public Stuff() 
        { 
        } 
         
        public void DoStuff() 
        { 
            Console.WriteLine("Hello World I’m doing stuff");
        } 
    } 
}

Code 2
 
It would be nice to have each time the real date-time in the generated comments, so change the comments adding an additional T4 Eval Statement (<#=  DateTime.Now #>) which changes the template according Picture 3. Make sure the generated code, will contain the current date and time.
 
Picture 3

Next add one more class named AnotherStuff having a standard constructor and a method named DoAnotherStuff. The declaration could look like in Code 3. Note we are repeating here some steps at least twice, which of course could be done in an optimized way as well.

using System;
namespace ConsoleAppT4 

    public class Stuff 
    { 
        public Stuff() 
        { 
        } 
         
        public void DoStuff() 
        { 
            Console.WriteLine("Hello World I’m doing stuff");
        } 
    } 
    
    public class AnotherStuff 
    { 
        public AnotherStuff() 
        { 
        } 
         
        public void DoAnotherStuff() 
        { 
            Console.WriteLine("Hello World I’m doing anotherstuff");
        } 
    } 
}

 

Code 3

For the reason of more compact code in the T4 template we are going to introduce T4 Class Sections (or simply helper sections). The general syntax is

<#+ here goes some content #>

Such sections works like routines or functions called repeatedly within the temple at code generation-time. Let’s extend our existing template with such T4 Class Section. We would like to create classes with a default constructor and a single method writing the class’s name into the console. Such T4 Class section could look like in Code 4.

using System;
namespace ConsoleAppT4
{
<# AddClassAndMethod("Stuff"); #>        
<# AddClassAndMethod("AnotherStuff"); #>       

<#+ private void AddClassAndMethod(string className)
{
#>
    public class <#= className #>
    {
        public <#= className #>()
        {
        }
        
        public void Do<#= className #>()
        {
            Console.WriteLine("Hello World I’m doing <#= className #>");
        }
    }
<#+ } #>
 
Code 4

Please note the Method AddClassAndMethod enclosed in a T4 Class Section. Also note the closing, rather very short part of this T4 Class Section at the end of the template (Picture 4). It consists of a single closing curly bracket belonging to opening curly bracket in the first part of the T4 Class Section. Between these parts are the lines of code placed into the output. Blank new lines (white spaces) matter and are not swallowed.

For more clarity the tangible T4 Editor’s coloring will greatly help you to better understand what’s going on. Note these T4 Class Sections are marked with a yellow background. Generally speaking yellow background code will run at code generation time and is not put directly into the output. Lines with white background however are copied directly in a 1: 1 manner into the result, except the T4 Eval Statements (colored in the background yellow as well).

Picture 4

Note furthermore that the AddClassAndMethod method is called twice from within out Template with different input parameters. The generated output result (Code 5) not surprisingly contains two classes named Stuff and AnotherStuff whereas these classes’ structure are identical according to the T4 Class Section.

// ——————————————
// <auto-generated>
//         This code was auto-generated 06/02/2010 16:22:22
// <auto-generated>
// —————————————–

using System;
namespace ConsoleAppT4
{
    public class Stuff
    {
        public Stuff()
        {
        }
        
        public void DoStuff()
        {
            Console.WriteLine("Hello World I’m doing Stuff");
        }
    }
        
    public class AnotherStuff
    {
        public AnotherStuff()
        {
        }
        
        public void DoAnotherStuff()
        {
            Console.WriteLine("Hello World I’m doing AnotherStuff");
        }
    }
       
}

Code 5

Conclusion: in this article you learned a few about the basic building blocks of any T4 Template. These blocks are  as follows:

  • T4 Code Section; Syntax: <# … #>
  • T4 Pragma Section, Syntax <#@ … #>
  • T4 Class Section; Syntax <#+ … #>
  • T4 Eval Statement; Syntax <#= … #>
Advertisements
This entry was posted in Uncategorized - Common. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s