T4 Template Design: Standalone Template


Standalone Template is one of T4 template design techniques that can be used to develop reusable templates. The main defines parameters as properties that retrieve their values from an external data store, such as CallContext or an XML file. The calling template uses T4 engine to compile the standalone template into a separate assembly and run the compiled code independently of the calling template.

Main Template

<#@ template language="C#" #>
<#@ import namespace="System.Runtime.Remoting.Messaging" #>
public class <#= ClassName #>
{
    public string Property
    {
        get { return _property; }
        set { _property = value; }
    }
}
<#+
    string ClassName
    {
        get { return (string)CallContext.LogicalGetData("ClassName"); }
    }
#>

Calling Template

<#@ template language="C#" hostspecific="True" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Runtime.Remoting.Messaging" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#
  CallContext.LogicalSetData("ClassName", "TestClass");
  string output = ProcessTemplate("Template.tt");
  Write(output);
#>
<#+
  string ProcessTemplate(string templateFileName)
  {
    string template = File.ReadAllText(Host.ResolvePath(templateFileName));
    Engine engine = new Engine();
    return engine.ProcessTemplate(template, Host);
  }
#>

Output

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

How It Works

The main template defines its parameters as read-only properties that get their values from the remoting CallContext, such as ClassName property in the example above. The calling template provides parameter values by placing them in the CallContext. It then uses T4 Engine to compile and execute the main template and save its output.

Pros

Standalone Template technique allows to parameterize a one-off template and reuse it to generate multiple artifacts of the same type. This technique provides good encapsulation of the main template and allows to compose templates to generate multiple outputs from a single calling template.

This technique can be used to invoke a T4 template from external code, such as a console application.

Cons

Standalone Template technique requires using an external, weakly-typed mechanism, such as CallContext or an XML file, to pass parameter values to the main template.

This technique does not allow to extend the main template without resorting to modification of the main template itself.

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.


Write a Comment

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

Reader Comments

Thank you for your interesting articles!!!
Do you have an example of invoking a T4 template from external code, such as a console application?

Best regards / Michael

You can use code shown in the “Calling Template” example in this article to do it.

  • Create a new console application
  • Add assemblies listed in < #@ import #> directives as references to the project
  • Copy the code from the < # statement block #> to the Main method
  • Change the “Write” method call to “Console.Write”
  • Copy the code from the < #+ class feature block #> to the Program class outside of the Main method

Let me know if this doesn’t work.

In trying to invoke the template from a console appliation, the Host property is no longer defined once the is moved into the Program class.

Chris,

The Host property is generated by T4 when hostspecific property of the template directive is set to true:
< #@ template hostspecific="True" #>. You will get a host object of a different type, but the property should still be there.

I am unable to find the Host property. though there is an interface ITextTemplatingHost. Please explain how to use the host property in code .

T4 generates Host property the hostspecific parameter of the template directive is True. Hope this helps.

But you cant use engine.ProcessTemplate without passing in a host in Code..

I have the same problem of Vipin.
I must use the template in a console application.
I folollow the point 2, but compiler don’t like it. And compiler says: “The name ‘Host’ does not exist in the current context”

How can I do?

Although you could implement a custom T4 host as described here, this is a non-trivial task. A much simpler option is to invoke TextTransform.exe and pass the parameters through either environment variables or a pre-defined external file.