http://blogs.clariusconsulting.net/kzu

Daniel Cazzulino's Blog

Go Back to
kzu′s Latest post

How to use T4 templates in WP7, Silverlight, Desktop or even MonoDroid apps

In other words, how to use T4 templates without ANY runtime dependencies? Yes, it is possible, and quite simple and elegant actually.

In a desktop project, just open the Add New Item dialog, and search for "text template":

image

From the two available templates, the one that gives you a zero-dependency runtime-usable template is the first one: Preprocessed Text Template.

Once unfolded, you get the .tt file, but also a dependent .cs file automatically generated. Note the Custom Tool associated with the file is TextTemplatingFilePreProcessor:

image

If you open up the .cs file, you will see that it doesn’t contain the rendered "Hello World!!!" I added in the .tt, but rather a full class named after the template file itself:

namespace ClassLibrary1
{
    using System;

    #line 1 "C:\Temp\ClassLibrary1\ClassLibrary1\PreTextTemplate1.tt"
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "10.0.0.0")]
    public partial class PreTextTemplate1 : PreTextTemplate1Base
    {
        public virtual string TransformText()
        {
            this.GenerationEnvironment = null;
            this.Write("Hello World!!!");
            return this.GenerationEnvironment.ToString();
        }
    }

    #region Base class
    ...
    #endregion
}

In order to render the template, we just need to create an instance of this template class, and invoke TransformText:

var template = new PreTextTemplate1();

Console.WriteLine(template.TransformText());

If you look at the generated template class (called the "rendering class"), you will see that it has no external dependencies whatsoever. You don’t need any extra reference in your project in order to compile it. None.

For Silverlight, WP7, MonoDroid and other custom project types, the item template will likely not appear in the dialog. But simply adding a text file with (using .tt or .t4 as a convention for the file extension) and setting the file Custom Tool property to TextTemplatingFilePreprocessor, you will get the same rendering class in those project types.

Now, how do you pass input data to the template? Well, being a partial class, you can add properties or custom constructors to it via another partial class file, or you can do it from within the template itself:

image

Note that class-level "features" (properties, constructors, fields, etc.) are defined at the bottom of the template, in <#+ #> sections.

Once we have the property declared, we can use it in the template itself:

image

Now when we instantiate the template, we can just set the "model" to render by setting the property:

var customer = LoadCustomer();
var template = new CustomerTemplate { Customer = customer };

Console.WriteLine(template.TransformText());

I hope the new Razor rendering engine also supports such a lightweight reuse approach.

Enjoy!

[PS: the T4 screenshots show the intellisense provided by VS2010 beta of Visual T4]

Comments

3 Comments

  1. I can’t get this to work as a preprocessed template to be run in a Silverlight application. The private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; member in the generated base class causes a compiler error. Once again, I want to use this at run time as a preprocessed template, adding the line in the template is non applicable.

    Do you have to create your own base class? Or do preprocessed templates just don’t work for Silverlight.

    Thanks,
    Aris J. Green

  2. Just create a class with that name in your project, that does nothing? ;)

  3. Hi,

    I want to create a Visual Studio Item Template that generates an Item (for eg. custom .aspx page) in the solution by executing T4 Template while adding it to the solution.
    I read the following post : http://stackoverflow.com/questions/805979/t4-templates-and-visual-studio-item-templates

    Is it possible to implement this without using GAX. I mean is it possible to start by using a standard project item template and T4 Templates only, which doesn’t require GAX.

    Please suggest how to do it.