T4 Template Directive
A Visual Studio T4 text template usually starts with a template directive, which specifies how the template should be processed. There should be no more than one template directive in a text template and any files that it includes.
For a general overview of writing text templates, see Writing a T4 Text Template.
<#@ template [language="VB"] [compilerOptions="options"] [culture="code"] [debug="true"] [hostspecific="true"] [inherits="templateBaseClass"] [visibility="internal"] [linePragmas="false"] #>
The template directive has several attributes that allow you to specify different aspects of the transformation. All the attributes are optional.
If the debug attribute is true, the intermediate code file will contain information that enables the debugger to identify more accurately the position in your template where a break or exception occurred.
For design-time templates the intermediate code file will be written to your %TEMP% directory.
To run a design-time template in the debugger, save the text template, then open the shortcut menu of the text template in Solution Explorer, and choose Debug T4 Template.
If you set the value of this attribute to true, a property named Host is added to the class generated by your text template. The property is a reference to the host of the transformation engine, and is declared as ITextTemplatingEngineHost. If you have defined a custom host, you can cast it to the custom host type.
Because the type of this property depends on the type of host, it is only useful if you are writing a text template that works only with a specific host. It’s applicable to design-time templates, but not run-time templates.
When hostspecific is true and you are using Visual Studio, you can cast this.Host to IServiceProvider to access Visual Studio features. You can also use Host.ResolvePath(filename) to obtain the absolute path of a file in the project. For example:
<#@ template debug="false" hostspecific="true" language="C#" #> <#@ output extension=".txt" #> <#@ assembly name="EnvDTE" #> <#@ import namespace="EnvDTE" #> <#@ import namespace="System.IO" #> <# // Get the Visual Studio API as a service: DTE dte = ((IServiceProvider)this.Host).GetCOMService(typeof(DTE)) as DTE; #> Number of projects in this solution: <#= dte.Solution.Projects.Count #> <# // Find a path within the current project: string myFile = File.ReadAllText(this.Host.ResolvePath("MyFile.txt")); #> Content of myFile is: <#= myFile #>
If you use the inherits and hostspecific attributes together, specify host="trueFromBase" in the derived class and host="true" in the base class. This avoids a double definition of the Host property in the generated code.
The language attribute specifies the language (Visual Basic or Visual C#) to use for the source code in statement and expression blocks. The intermediate code file from which the output is generated will use this language. This language is not related to the language that your template generates, which can be any kind of text.
You can specify that the program code of your template can inherit from another class, which can also be generated from a text template.
You can use inheritance between run-time text templates to create a basic template that has several derived variants. Run-time templates are those that have the Custom Tool property set to TextTemplatingFilePreprocessor. A run-time template generates code that you can call in your application to create the text defined in the template. For more information, see Run-Time Text Generation with T4 Text Templates.
If you do not specify an inherits attribute, a base class and a derived class are generated from your text template. When you specify an inherits attribute, only the derived class is generated. You can write a base class by hand, but it must provide the methods that are used by the derived class.
More typically, you specify another preprocessed template as the base class. The base template provides common blocks of text, which can be interleaved with text from the derived templates. You can use class feature blocks <#+ ... #> to define methods that contain text fragments. For example, you can place the framework of the output text in the base template, providing virtual methods that can be overridden in derived templates:
You can build the base and derived classes in different projects. Remember to add the base project or assembly to the derived project’s references.
You can also use an ordinary hand-written class as the base class. The base class must provide the methods used by the derived class.
If you use the inherits and hostspecific attributes together, specify hostspecific="trueFromBase" in the derived class and host="true" in the base class. This avoids a double definition of the Host property in the generated code.
A design-time text template is a file for which Custom Tool is set to TextTemplatingFileGenerator. The template generates an output file of code or text, which forms part of your Visual Studio project. To generate the output file, the template is first translated into an intermediate program code file, which you do not usually see. The inherits attribute specifies the base class for this intermediate code.
For a design-time text template, you can specify any base class that is derived from Microsoft.VisualStudio.TextTemplating.TextTransformation. Use the <#@assembly#> directive to load the assembly or project that contains the base class.
For more information, see "Inheritance in Text Templates" in Gareth Jones’ Blog.
Setting this attribute to false removes the tags that identify your line numbers within the generated code. This means that the compiler will report any errors by using line numbers of the generated code.This gives you more debugging options, as you can choose to debug either the text template or the generated code.
This attribute can also help if you’re finding the absolute filenames in pragmas are causing distracting merges under source code control.