T4 Template Design: Merged Template Class


Merged Template Class is one of T4 template design techniques that can be used to develop reusable templates. It uses class feature blocks to define parameters as fields or properties in the main template. The calling template uses an include directive to merge code of main template with the code of the calling template and assigns parameter values in a statement block.

Main Template

public class <#= ClassName #>
{
    <# WritePropertyAttributes(); #>
    public string Property
    {
        get { return _property; }
        set { _property = value; }
    }
}
<#+
    string ClassName;
#>

Calling Template

<#@template language=C##>
<#
    this.ClassName = “TestClass”;
#>
<#@include file=Template.tt#>
<#+
    void WritePropertyAttributes()
    {
#>
[DataMember]
<#+
    }
#>

Template Output

public class TestClass
{
    [DataMember]
    public string Property
    {
        get { return _property; }
        set { _property = value; }
    }
}

How It Works?

The main template defines parameters as fields or properties in a class feature block. The calling template specifies parameter values in a statement block and uses an include directive to merge the main template definition into the calling template. In the example above, ClassName field serves as a template parameter.

The main template defines extension points by calling a predefined method. The calling template implements this method. In the example above, WritePropertyAttributes method serves as an extension mechanism that allows template user to provide custom attributes for a property generated by the main template.

Here is what the calling template looks like when it is compiled by T4.

using System;
using Microsoft.VisualStudio.TextTemplating;  

namespace Microsoft.VisualStudio.TextTemplating4B3717E31A786AD
{
  public class GeneratedTextTransformation: TextTransformation
  {
    public override string TransformText()
    {
      this.ClassName = “TestClass”;
      this.Write(“public class “);
      this.Write(ToStringHelper.ToStringWithCulture(ClassName));
      this.Write(“\r\n{\r\n\t”);
      WritePropertyAttributes();
      this.Write(“\tpublic string Property\r\n\t{\r\n\t\t”+
          “get { return _property; }\r\n\t\t”+
          “set { _property = value; }\r\n\t}\r\n}\r\n”);
      this.Write(“\r\n”);
      return this.GenerationEnvironment.ToString();
    }
    void WritePropertyAttributes()
    {
        this.Write(“[DataMember]\r\n”);
    }
    string ClassName;
  }
}

Pros

This technique allows to quickly parameterize a one-off template and reuse it to generate multiple artifacts of the same type. It also allows to extend the main template in the calling template without resorting to modification of the main template itself.

Cons

This technique provides poor encapsulation of the main template. As the main template and the calling template are merged into one compiled class, all implementation details of the main template become exposed to the calling template.

This technique does not define the interface between the main template and the calling template explicitly. In order to use the main template, user has to fully understand its implementation. As a result, this implied interface is very fragile. Adding a new extension method to the main template breaks the calling templates by introducing a call to non-existent method.

This technique doesn’t allow to compose templates. In other words, users cannot use two or more main templates to generate multiple outputs from a single calling template

Conclusion

This technique allows to quickly parameterize a one-off template and start generating multiple artifacts of the same type. It is appropriate during early stages in adoption of T4 code generation or for simple code generation scenarios. Due to weak encapsulation and fragile, implicit interface between main and calling templates, this technique does not scale beyond a single project or a single development team.

About T4

T4 (Text Template Transformation Toolkit) is a template-based code generation engine. It is available in Visual Studio 2008 and as a download in DSL and GAT toolkits for Visual Studio 2005. T4 engine allows you to use ASP.NET-like template syntax to generate C#, T-SQL, XML or any other text files.

For more information about T4, check out my previous article.

Information and Links

Join the fray by commenting, tracking what others have to say, or linking to it from your blog.


Other Posts
T4 Template Design: Template Method
T4 Template Design

Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.

Reader Comments

Hi,
I really want to use t4 to speed up my development ,I think you have done a magnificient job with those small tutorials.
What about if I wanted to integrate with windows App?
Example
A propertyGrid + btnGenerate
Where a can specify class Name-Namespace -output folder etc…
Then press btnGenerate and this will pass all these values to the templates.
A tutorial on how to call the t4 template from a windows app and pass values would be fantastic!!!.

thanks
gabriel

Gabriel,

You can call a template from a windows app using <a href=”http://www.olegsych.com/2008/04/t4-template-design-standalone-template/”Standalone Template design technique. To make parsing properties and their types easier, you can use the directive.

Implementing this would certainly make working with T4 very similar to CodeSmith. However, I question whether it would make working with templates easier. With CodeSmith, you use special XML files to store these template property values. With T4, such as when using Nested Template Class technique, you specify and store property values in C# or Visual Basic code. I find working with C# code more straightforward than working with XML.

Although for a template user, being able to specify template property values visually, in a property grid, is nice, implementing it requires a lot of extra work for the template developer. I haven’t found time and justification for this investment yet.

Oleg