madhavrao… » Code Generators

The five built-in directives are:

  1. Assembly
  2. Import
  3. Include
  4. Template
  5. OutputĀ 

Assembly

The assembly directive identifies an assembly to be referenced so that you can use types within that assembly from code in the text template. Using the assembly directive is equivalent to using the Add Reference feature in Visual Studio.

In the following example, the directive name is assembly, the parameter name is name, and the parameter value is SomeLibrary.DLL:

<@ assembly name=”SomeLibrary.DLL” #>

Import

By using the import directive, you can refer to types in a text template without providing a fully qualified name.

In the following example, the directive name is import, the parameter name is namespace, and the parameter value is System.Diagnostics:

<#@ import namespace=”System.Diagnostics” #>

Include

The include directive processes text from the specified file as if that text were included verbatim in the template currently being processed. In the following example, the name of the directive is include, the parameter name is file, and the parameter value is C:\test.txt:

<#@ include file=”c:\test.txt” #>

Template

By using the template directive, you can specify characteristics of the generated transformation class, such as code language, class inheritance, culture, and the ability to debug. The template directive takes the following parameters, each of which is optional:

Parameter Default Value Acceptable Value Details
language C# C#, VB This parameter specifies which language, either Visual Basic or C#, has been used for code that is inside statement and expression blocks. All code that the engine generates in the transformation class must be expressed by using this language. The following example shows how to specify the Visual Basic language: <#@ template language=”VB”#>
inherits TextTransformation Any Class that derives from TextTransformation This parameter 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”#>This concept is similar to ASP.Net Pages. Where markup is defined in aspx file and code behind is in .cs or .vb file or in some dll.
culture “”, the invariant culture A culture expressed as a string in the form xx-XX. For example, en-US, ja-JP, de-CH, de-DE, and others. This parameter specifies the culture to use when an expression block is converted to text.
debug true true, false This parameter specifies whether debugging is enabled. The following example shows how to enable debugging:
<#@ template debug=”true” #>
hostspecific false true, false This parameter is 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

Output

By using the output directive, you can specify characteristics of the generated text output, such as the file name extension. The output directive takes the following parameters, each of which is optional:

Parameter Default Value Acceptable Value Details
extension .cs Any string that satisfies the file systems rule for file extension. This parameter specifies the extension of the generated text output file. For example, you can specify a .cs or .vb extension if the generated text output is a code file. It is important to remember that the file name extension indicates only that the file is intended to be a particular format. The writer of the text template must make sure that the generated text meets the requirements of the intended format.<#@ output extension=”.txt” #>
<#@ output extension=”.htm” #>
<#@ output extension=”.cs” #>
<#@ output extension=”.vb” #>
encoding “Default”, the current ANSI code page of the system. Any of the following members of the Encoding class expressed as a string: Default, ASCII, BigEndianUnicode, Unicode, UTF32, UTF7, UTF8. This parameter specifies what encoding should be used when the generated text output file is created.<#@ output encoding=”ASCII”#>
<#@ output encoding=”UNICODE”#>
<#@ output encoding=”UTF8″#>

Share this post :

Directives and directive processors provide additional functionality to text templates. This functionality can be a simple as the ability to specify the extension of the output file or as complex as custom directive processors that read data from a database.

A directive processor contains one or more directives, and the same directive processor can process more than one directive. As an analogy, you can think of directive processors as classes, and you can think of directives as methods in those classes. You call directives directly from your text templates.

Example of Directives are:

  1. output: this is used to specify extension of the file.
  2. template: this is used to specify various properties of the template, one of which is language used to write control logic.

Directives can be classified into three types:

  1. Built-In Directives
  2. Generated Directives
  3. Custom Directives

Built-In Directives

Built-in directives are provided by the text template transformation toolkit. By using built-in directives, you can specify common options such as the programming language of the text template and the extension of the output file. There are five built-in directives: assembly, import, template, output, and include.

Generated Directives

Generated directives are based on the domain-specific language that you create. If you call a generated directive, you can access models from the statements and expressions in text templates.

Custom Directives

One can write custom directive processors to provide custom functionality to text templates. Custom directive processor can be used any time that one want to access external data or resources from a text template.

Different text templates can share the functionality that a single directive processor provides, so directive processors provide a way to factor code for reuse. The built-in include directive is similar, because you can use it to factor out code and share it among different text templates. The difference is that any functionality that the include directive provides is fixed and does not accept parameters. If you want to provide common functionality to a text template and allow the template to pass parameters, you must create a custom directive processor.

Some examples of custom directive processors could be:

  1. A directive processor to return data from a database that accepts a user name and password as parameters.
  2. A directive processor to open and read a file that accepts the name of the file as a parameter.

Host in T4 is responsible for anything that relates to external environment, including the following:

  1. Providing a file or an assembly if the engine or a directive processor requests one.
  2. The host can search directories and the global assembly cache to locate files and assemblies. (This is implemented in “ResolveAssemblyReference” method of host class)
  3. The host can locate custom directive processor code for the engine. (This is implemented in “ResolveDirectiveProcessor” method of host class)
  4. The host can open and read files and return their contents as strings. (This is implemented in “LoadIncludeText” method of host class. If it returns true then included text in “content” parameter and location of the file in “location” paramter)
  5. Providing lists of standard assemblies and namespaces to the engine. (This is implemented in host class as “StandardAssemblyReferences” and “StandardImports” properties)
  6. The engine uses these assemblies and namespaces when it creates the generated transformation class as part of the text template transformation process.
  7. Providing the application domain that the engine uses to compile and execute the generated transformation class. (This is implemented in “ProvideTemplatingAppDomain” method of host class)
  8. Writing the generated text output file. (Host provides file-encoding and file content to the calling code, actual writing is done my class which holds engine, and host instance)
  9. Setting the default extension for the generated text output files. (Default extension can be changed in host object at runtime by calling “SetFileExtension” method. In case extension is specified in template file using “output” directive it will override everything else.)
  10. Receiving the text template transformation errors from the engine and deciding what to do with them. For example, the host can display the errors in the user interface or write them to a file. (This is implemented in “LogErrors” method of host class. Engine calls this method to pass compile errors to host)
  11. Helping a directive processor resolve a required parameter value if a user has called a directive without providing a value. (This is implemented in “ResolveParameterValue” method of host class)
  12. The directive processor can specify the name of the directive and the parameter and ask the host to provide a default value if it has one.

If you want to use the text template transformation functionality in a custom application, you can write a custom text template host. To create a custom host, you create a class that inherits from ITextTemplatingEngineHost

The text template transformation process has three components: the host, the engine and the directive processor.

Engine: The engine component controls the process and interacts with the host and zero or more directive processors to complete the process.

Host: The host is responsible for all input and output, locating files and anything else related to external environment. Visual Studio is example of Host, one can create custom host by implementing interface ITextTemplatingEngineHost from Microsoft.VisualStudio.TextTemplate assembly. Details of Creating Custom Text Template Host are covered in MSDN

Directive Processors: Directive processors are classes that handle directives in text templates. One can typically use directives to provide data from an input source (for example, from a model) to a text template. When you use Domain-Specific Language Tools, a directive processor is generated for each domain-specific language, so that text templates can access the models in that language as input sources. One can also write custom directive processors. Details of Creating Custom Text Template Directive Processors is covered in MSDN.

Text Template Transformation process is a two step process, in first step temporary class (generated transformation class) is created based on text template and in second step engine complies and executes the generate transformation class to generate text output.