Understanding T4: Class Feature Blocks


Here is how T4 documentation on MSDN defines class feature blocks.

You can use the class feature blocks in your text templates to add helper functions. Helper functions enable you to avoid repeating common code. The general syntax is:

<#+ FeatureCode #>

Here is what happens under the hood.

Template

<#@ template language="C#"#>
<# HelloWorld(); #>
<#+
    private void HelloWorld()
    {
        this.Write("Hello World");
    }
#>


Compiled Template

using System;
using Microsoft.VisualStudio.TextTemplating;  

namespace Microsoft.VisualStudio.TextTemplatingD6871B481C94B9A9
{
    public class GeneratedTextTransformation: TextTransformation
    {
        public override string TransformText()
        {
            HelloWorld();
            return this.GenerationEnvironment.ToString();
        }
        private void HelloWorld()
        {
            this.Write("Hello World");
        }
   }
}


Output

Hello World

As you can see, T4 copied contents of the class feature block to the "class" area of the GeneratedTextTransformation. Notice that call to HelloWorld method inside the statement block was placed in the generated TransformText method. Any text blocks preceding class feature block would be placed as Write method calls inside TransformText method as well.

Class feature blocks are not limited to just helper functions. They can also contain fields, constants, properties, or any other programming constructs that can be placed in a C# class. T4 also allows using text and expression blocks inside of "class features".

Template

<#@ template language="C#" #>
<# HelloWorld(); #>
<#+
    private string _field = "classy";
    private void HelloWorld()
    {
        for(int i = 1; i <= 3; i++)
        {
#>
Hello <#=_field#> World <#= i #>!
<#+
        }
    }
#>


Compiled Template

using System;
using Microsoft.VisualStudio.TextTemplating;  

namespace Microsoft.VisualStudio.TextTemplatingB29FB374409DFE
{
    public class GeneratedTextTransformation: TextTransformation
    {
        public override string TransformText()
        {
            HelloWorld();
            return this.GenerationEnvironment.ToString();
        }  

        private string _field = "classy";
        private void HelloWorld()
        {
            for (int i = 1; i <= 3; i++)
            {
                this.Write("Hello ");
                this.Write(ToStringHelper.ToStringWithCulture(_field));
                this.Write(" World ");
                this.Write(ToStringHelper.ToStringWithCulture(i));
                this.Write("!\r\n");
            }
        }
    }
}


Output

Hello classy World 1!
Hello classy World 2!
Hello classy World 3!

Notice that text and expression blocks in this template were transformed into Write method calls inside of the HelloWorld function declared in the class feature block of the template.

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.

Ready for more? Read about <#@ template #> directive or go back to the overview.


Write a Comment

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

Reader Comments

[…] template that builds classes from the XML file contains a class feature block (for details see Oleg’s blog), called GenerateClass, which takes two parameters. The first is the fully qualified name of the […]

[…] Class feature blocks  (virtual methods) Include directive (template fragment libraries) […]

[…] Class feature blocks  (virtual methods) Include directive (template fragment libraries) […]

[…] Class feature blocks  (virtual methods) Include directive (template fragment libraries) […]

Oleg,

How can I view the Compiled Template - I can’t seem to find it.

[…] you can see – very simple, and very single purpose.  It’s just a definition in a class feature block of a method to write out a header.  A lot of my helpers are just like this – either one […]