***Disclaimer: This information applies to Visual Studio 2010 Beta 1 only.***
In the first part I covered the details of the T4 Preprocessing API.
Now it’s time to create a preprocessed text template and mimic the GAX property directive processor feature.
Let’s add a preprocessed text template. For that purpose there is a new item template in the VS10 Add new item dialog:
After we add a pre-compiled template item, we can see the output of the transformation:
As you can see, the namespace is calculated from the project default namespace property, and the tt item name is used to calculate the class name.
Using properties to mimic the GAX PropertyProcessor directive
After the TemplatedPreprocessor runs we end up with a template class, which is just a regular class with some helper methods to write the transformation.
These methods are similar to the ones provided in the base TextTransformation class. But to remove the dependency to the Microsoft.VisualStudio.TextTemplating.10.0 assembly those methods are now part of our template class.
To add properties that will be consumed inside the template, it is just a matter of declaring a partial class and adding them there:
namespace PreTT
{
public partial class MyPreTextTemplate
{
public string MyProperty { get; set; }
}
}
Then from within the template we can just refer to the property:
<#@ template language="C#" #>
MyProperty value is <#= this.MyProperty #>
To test the transformation we create an instance of the template class and we call the TransformText method:
public static void Main(string[] args)
{
Console.WriteLine(
new MyPreTextTemplate { MyProperty = "Foo" }
.TransformText());
Console.Read();
}
And the transformation output is :
Pablo
***Disclaimer: This information applies to Visual Studio 2010 Beta 1 only.***
Gareth wrote some time ago two nice posts about the T4 Preprocessing feature:
This post will have two parts. The first one will cover the details of the new API and the second one will show how to create a preprocessed text template and the how to mimic the GAX property directive processor feature using partial classes.
The precompiled text template feature is really useful in scenarios where the text templates doesn't change at run time.
Let’s say that we have an application that uses a set of templates for code generation, and those templates never change.
This is a perfect fit for precompiled templates. Instead of deploying a set of .tt files as part of the application, we can pre-compile them and they now can be part of the main application assembly or any other component assembly.
This *drastically* improves the performance because on each transformation this is what happens behind the scenes in order to get a transformation result:
- A template processor calls the template engine that:
- Parses the template
- Processes the directives
- Generates the template class
- If the text template doesn’t cache the assemblies (CacheAssemblies="false”) or if the application domain needs to be recycled
- The template host creates an application domain
- The template host resolves the assembly references that are defined in the template
- The template host creates a transformation runner that:
- Compiles the generated template class into a temporary assembly
- Loads the temporary assembly into the application domain
- Calls the “TransformText” method that returns the transformation result
- Else
- The template host creates a transformation runner that:
- Uses the cached assembly
- Calls the “TransformText” method that returns the transformation result
With a precompiled template we skip all the steps in *bold* and we just call the “TransformText” method in the compiled template class that is part of the application or component assembly.
Also, having a precompiled template means that a transformation can run in any .Net environment without the need of having Visual Studio or the Microsoft.VisualStudio.TextTemplating.* assemblies installed.
API changes to support template preprocessing
- The following two interfaces were updated to include the new PreprocessTemplate method:
public interface ITextTemplating
{
string PreprocessTemplate(string inputFile, string content, ITextTemplatingCallback callback, string className, string classNamespace, out string[] references);
}
public interface ITextTemplatingEngine
{
string PreprocessTemplate(string content, ITextTemplatingEngineHost host, string className, string classNamespace, out string language, out string[] references);
}
- A new TemplatedPreprocessor custom tool /single file generator was added:
This new custom tool is the responsible for creating the template class at design time. This tool basically does the following:
- Parses the template
- Processes the directives
- Generates the template class
Stay tuned,
Pablo