Understanding T4: <#@ template #> directive
Here is how MSDN documentation defines the template directive.
By using the template directive, you can specify characteristics of the generated transformation class. For example, you can specify code language, class inheritance, culture, and the ability to debug.
This directive contains several parameters. Most of them are well described in MSDN documentation. From code generation prospective, several parameters deserve more attention.
Language parameter
As the documentation explains, language parameter specifies which language, either Visual Basic or C# is used in code blocks of the template. Acceptable values include "C#" and "VB". By default, T4 will use version 2 of the C# and Visual Basic compilers. In Visual Studio 2008, you can take advantage of the new language features provided by version 3.5 of the compilers by including version in the parameter value [1].
<#@ template language="C#v3.5" #>
or
<#@ template language="VBv3.5" #>
New assemblies shipped with version 3.5 of the .NET framework need to be referenced explicitly:
<#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #>
Debug parameter
As the documentation explains, setting the debug parameter allows you to debug templates. In order to make it possible, T4 saves generated source code, .NET assembly and debugging symbols in the TEMP folder (%USERPROFILE%\Local Settings\Temp). The .cs file contains source code of the GeneratedTextTransformation. The .cmdline file contains command line options used to compile .cs file into .NET assembly (the .dll file).
Template
<#@ template language="C#" debug="True" #>
Generated Temporary Files
csqg2m5s.0.cs csqg2m5s.cmdline csqg2m5s.dll csqg2m5s.err csqg2m5s.out csqg2m5s.pdb csqg2m5s.tmp
Note that setting the language parameter to "VB" causes T4 to generate Visual Basic code and use vbc instead of csc to compile the GeneratedTextTransformation.
Inherits parameter
Here is how MSDN documentation defines the inherits parameter of the template directive.
Specifies which class should be used as the base class for the generated transformation class. The following example shows how to specify that the SomeClass class should be used:
<#@ template inherits="SomeClass"#>
In order to demonstrate use of this parameter, we need to have a class that inherits from TextTransformation. Here is an example of such class.
MyTextTransformation.cs
using System; using Microsoft.VisualStudio.TextTemplating; namespace ClassLibrary1 { public abstract class MyTextTransformation: TextTransformation { protected void SayHello() { Write("Hello"); } } }
With previous code compiled in ClassLibrary1.dll, we can see how T4 uses it under the hood.
Template
<#@ template inherits="MyTextTransformation" debug="True" #> <#@ assembly name="C:\ClassLibrary1\bin\Debug\ClassLibrary1.dll" #> <#@ import namespace="ClassLibrary1" #> <# SayHello(); #>
Compiled Template
using System; using Microsoft.VisualStudio.TextTemplating.VSHost; using ClassLibrary1; namespace Microsoft.VisualStudio.TextTemplating813D4B84ADE998BE3BDDB17BECBBF62A { public class GeneratedTextTransformation: MyTextTransformation { public override string TransformText() { SayHello(); return this.GenerationEnvironment.ToString(); } } }
Output
Hello
As you can see, the template above uses the inherits attribute of the template directive to change base class of GeneratedTextTransformation to MyTextTransformation. Having replaced the base class, template can access its methods, such as SayHello. It is important to note that for this template to compile, T4 needs be able to find the base class. In this example, we are using the assembly directive to let T4 know the assembly where this class is defined and the import directive to specify it’s namespace. Using the assembly directive would not be necessary if the base class was defined in an assembly stored in GAC. Using the import directive would not be necessary if we specified full name of the class in the inherits attribute
Hostspecific parameter
Here is how MSDN documentation defines the hostspecific parameter of the template directive
Used only with custom hosts. If you set the value of this parameter to true, you can access a property called Host in your text template. The property is a reference to the object that hosts the engine. You should set hostspecific to true only if you want to write a text template that is specific to a custom host and the text template calls the host at execution time. When hostspecific is true and you are using Visual Studio, you can call GetService to update your text templates.
Here is what happens under the hood.
Template
<#@ template language="C#" hostspecific="True" #> Generated by <#= Host.TemplateFile #>
Compiled Template
using System; using Microsoft.VisualStudio.TextTemplating; namespace Microsoft.VisualStudio.TextTemplatingEA2810A00CCCB9610 { public class GeneratedTextTransformation: TextTransformation { public override string TransformText() { this.Write("Generated by "); this.Write(ToStringHelper.ToStringWithCulture( Host.TemplateFile)); return this.GenerationEnvironment.ToString(); } private ITextTemplatingEngineHost hostValue; public virtual ITextTemplatingEngineHost Host { get { return this.hostValue; } set { this.hostValue = value; } } } }
Output
Generated by C:\...\HostSpecificParameter.tt
As you can see, this template sets the hostspecific parameter to True, which made T4 add Host property to the GeneratedTextTransformation. This property returns ITextTemplatingEngineHost interface, which provides access to several important properties and methods, such as ResolvePath which can be used to resolve file paths relative to the location of the template file into absolute paths.
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 <#@ output #> directive or go back to the overview.
References
- Enabling C# or VB 3.5 inside a text template by Pablo Galiano



Hi, Oleg!
But what about the “inherits” attribute?
I can’t force a T4 template to inherit from my class, an inheritor of TextTransformation.