Using T4 to generate content at runtime

Share on:

UPDATE 9 April 2014: The source is also available on GitHub** **

T4 (the Text Template Transformation Toolkit) is slowly becoming more widely known as a way to generate code to be compiled and used alongside hand-written code. Frameworks such as the Entity Framework V4 have adopted it for its code generation, allowing you to simply switch out the default class template for an alternative, e.g. POCO entity classes.

Whilst it seems to be fairly well known that T4 can be used to generate output at design time, it is less well known that you can actually use a T4 template at runtime as well. An example where you might want to do this is the generation of email content - this article will demonstrate how you might go about this.

Getting set up

If you want to skip to the end, the final code can be downloaded here.

First up, create a new console application, and add a very simple Customer class (we need to have someone to generate an email for, after all!):

image

Customer is defined as:

1public class Customer
2{
3    public string Name { get; set; }
4    public DateTime LastLoginDate { get; set; }
5}

Now add a new Preprocessed Text Template, calling it CustomerEmailTemplate.tt.

image

You’ll see a new editor looking something like this: (Note that I’m using Tangible Engineering’s excellent T4 editor extension, which is why the code is highlighted nicely)

image

Writing the template

Now we have a template file, lets add some content: (For simplicity we’ll generate a plain text email, although there is absolutely nothing stopping you from generating HTML - it’s still only text after all.)

 1<#@ template language="C#" #>
 2<#@ parameter
 3 name="Customer"
 4    type="ConsoleApplication1.Customer" #>
 5
 6Hi <#= Customer.Name #>,
 7
 8Thanks for logging onto our application on <#=
 9 Customer.LastLoginDate.ToString("d MMMM yyyy") #>!
10
11Please be sure to come back again soon!
12
13The Email Generation Co.

If you’ve used ASP.NET this should look fairly familiar, except in place of <% %> tags we have <# #>. The <#@ parameter #> declaration, as you might have guessed, is how we are going to pass information into a template. It has to be given a name, which is referenced later on in the template, and a type.

Using the template

Using the template is almost as easy as writing it - you can get output in 3 steps:

  1. Create a new instance of the template
  2. Set the template parameters by configuring then initializing the session
  3. Calling TransformText.

In the Main method in Program.cs, add the following code:

 1var customer = new Customer
 2{
 3    Name = "Jeffery",
 4    LastLoginDate = new DateTime(2009, 11, 2, 19, 23, 32)
 5};
 6
 7var template = new CustomerEmailTemplate();
 8template.Session = new Dictionary<string, object>()
 9{
10    { "Customer", customer }
11};
12
13template.Initialize();
14Console.WriteLine(template.TransformText());

The Session object is just a dictionary of name-value pairs. Once the Session has been set, you must call Initialize, otherwise you’ll get an error calling TransformText.

If you run the code you should hopefully see this output:

image

That’s all folks

One of the things I really like about pre-processed text templates is that you don’t have to add any additional references to your code (Visual Studio or otherwise) - they are completely self contained. If you’re interested in exactly they’re doing, have a look at the generated CustomerEmailTemplate.cs file. As a side-note, if you’re having problems structuring your code and things aren’t compiling, I have found that it’s sometimes useful to have a peek inside the generated file to see exactly what’s being put there - a misplaced brace is sometimes easier to spot there.

Whilst this was clearly a very simple and contrived example, hopefully you get the idea that T4 can be a very powerful tool at run-time as well as design-time.