The best kept secret in Redmond, WA are the new T4 Preprocess Text Templates that shipped in Visual Studio 2010 Beta1 and Beta2. In just a few minutes, you’ll be in the know and using them.
Background – Condensed
T4 = text template transformation toolkit
T4 templates have been available since Visual Studio 2005 and are part of DSL (Domain Specific Languages) documentation.
In Visual Studio 2010, the templates are MUCH easier to use because they are preprocessed. When you save your T4 template, it is compiled. The T4 template is now "processed" at compile time. This was not the case in previous releases.
Your compiled template is just another type in an assembly that you can now instantiate and call its single method, TransformText
. The only run-time requirement to use T4 templates is the .NET 2.0 Framework.
Prerequisites
- Visual Studio 2010
- T4 Editor Plug In
- Visual Studio 2010 does not provide any editing assistance when editing T4 templates (.tt files). You can search the Internet for T4 Editor and you’ll find some information and products.
- I’m currently using the Tangible T4 Editor (free) that you can get on the Visual Studio Gallery here:
Our Scenario
We have been tasked with creating some code that we can pass data fields to and that code will create a VB.NET property. This code will be part of a larger program that is fed information and creates class files.
Before T4 Preprocessed templates, we had several options available to us. Write code to spit out the required property, buy a 3rd party product, use CodeDom, etc.
Since we just installed Visual Studio 2010 Beta2, we are going for the productive, inexpensive, simple and out of the box solution, T4 Preprocessed Text Template.
Our Test Bench
This simple application simulates the data harness that will ultimately feed our T4 template and consume its output. Set a few data fields and press Generate Code.
Code Generation – It’s All About the Data
Code generation requires metadata to drive the output. With the new T4 templates, getting metadata into your T4 template is a simple matter of a partial class. The members in the partial class are available at design time and run-time. I know this seems so simple, but T4 did not always work this way. Now you have full design time strong typing and instant compile time verification of your template and code.
To keep this example as simple as possible, I’ve exposed the metadata directly as properties and passed values for them in the constructor of our Partial Class PropertyTemplate. For simple scenarios, this is totally fine. For larger or multi-language code generation applications, a better solution is to expose the metadata through an Interface. The Interface type can contain metadata and helper methods that can be used in your T4 template.
Kathleen Dollard and I have spoken a good bit about this and think using Interfaces for metadata and helper methods makes the most sense. I’m sure Kathleen will write more on this subject and I know I will.
In the below T4TemplateLibrary
project, you can see how I’ve set up the project. I had to turn on "Show All Files" to see the hidden file, "PropertyTemplate.vb" below the "PropertyTemplate.tt" file.
Open the hidden "PropertyTemplate.vb" file up and you will see the type of code you and I used to have to write to generate code. Now T4 does it for us!
The below partial class is overly simple and exposes metadata that will be consumed by the T4 template.
Namespace My.Templates
Partial Public Class PropertyTemplate
Public Property PropertyName As String = String.Empty
Public Property BackingField As String = String.Empty
Public Property TypeName As String = String.Empty
Public Property IsShared As Boolean = False
Public Property RaisePropertyChangedMethodName As String = String.Empty
Public Property IsReadOnly As Boolean = False
Public Property Scope As String = String.Empty
Public Property IsSetterPrivate As Boolean = False
Public Sub New(ByVal strScope As String, ByVal bolIsShared As Boolean,
ByVal bolIsReadOnly As Boolean, ByVal bolIsSetterPrivate As Boolean,
ByVal strPropertyName As String, ByVal strBackingField As String,
ByVal strTypeName As String, ByVal strRaisePropertyChangedMethodName As String)
Me.Scope = strScope
Me.IsShared = bolIsShared
Me.IsReadOnly = bolIsReadOnly
Me.IsSetterPrivate = bolIsSetterPrivate
Me.PropertyName = strPropertyName
Me.BackingField = strBackingField
Me.TypeName = strTypeName
Me.RaisePropertyChangedMethodName = strRaisePropertyChangedMethodName
End Sub
End Class
End Namespace
T4 Template
To add a T4 template to your project, select Add New Item, then type "preprocessed" in the search box. Select the Preprocess Text Template.
If you used classic ASP, then T4 template editing is a skill you already have. In classic ASP, we used <%
and <%=
. In T4, we use <#
and <#=
. The reason for this change is so that T4 can be used to generate classic ASP and ASP.NET code. If you didn’t have the joy of shipping classic ASP web sites, no worries. 15 minutes of trial and error and you’ll be fully qualified.
The below image shows the free Tangible T4 Editor Plug-In IntelliSense in action. It provides IntelliSense for T4 directives and template specific constructs like <#
. It also colorizes the template code. Colorizing makes editing the template much easier too. One current limitation is that its IntelliSense engine does list member properties defined in the partial class for the template.
The below code block is the T4 template. It has a language directive at the top followed by static text and code blocks.
<#@ template language="VB" #>
<#= Me.Scope #><#= IIF(Me.IsShared, " Shared","") #>
<#= IIF(Me.IsReadOnly, " ReadOnly", "") #> Property <#= Me.PropertyName #> As <#= Me.TypeName #>
Get
Return <#= Me.BackingField #>
End Get
<# If Not Me.IsReadOnly Then #>
<#= IIF(Me.IsSetterPrivate, " Private ","") #>Set(ByVal value As <#= Me.TypeName #>)
<# If String.IsNullOrEmpty(Me.RaisePropertyChangedMethodName) Then #>
<#= Me.BackingField #> = value
<# Else #>
<#= Me.BackingField #> = value
<#= String.Format("{0}(""{1}"")", Me.RaisePropertyChangedMethodName, Me.PropertyName) #>
<# End If #>
End Set
<# End If #>
End Property
<#=
is the same as the ASP Response.Write
. It writes the result of the expression into the template. For example, if the Scope is Public
, <#= Me.Scope #>
would yield Public
when the template is transformed at run-time.
<#
is the beginning of a code block. Notice how the IsReadOnly
property is tested. Basic on the result, an entire block of code can either run or be by-passed. This feature is so cool when you bring loops from LINQ queries into the picture.
One thing you’ll notice is that all the code blocks are left justified. Yes, this makes reading the template a little harder. However, if you don’t do this, the resulting code will be indented the same amount as the code block indentation.
So what I do when editing my templates is to indent everything to make it easier to edit the template. When I"m done, I go back and move the code to the left.
Run-Time Rendering of T4 Templates
Dim t As New PropertyTemplate(
Me.cboScope.SelectedItem.ToString,
Me.chkIsShared.IsChecked.Value,
Me.chkIsReadOnly.IsChecked.Value,
Me.chkIsSetterPrivate.IsChecked.Value,
Me.txtPropertyName.Text,
Me.txtBackingField.Text,
Me.cboTypeName.SelectedItem.ToString,
Me.cboRaisePropertyChangedMethodName.SelectedItem.ToString)
Dim strResult As String = t.TransformText
Instantiate the template, call the TransformText
method. Not very sexy, but powerful!
Download
Alternate Download Site
Some corporate firewalls do not allow access to Windows Live Sky Drive. You can download the installer here. Remember to rename the file from .doc to .zip. This is a requirement of WordPress.
Links
Close
There is a fair amount of information on Visual Studio 2005/2008 T4 templates. When reading these blog posts, magazine articles and MSDN Documentation, keep in mind that the new T4 templates do not have wide spread documentation yet. Most of what you will find is applicable to editing of the templates and directives used in the templates. Beyond that, just filter the information and you’ll stay on course.
Visual Studio 2010 T4 Preprocessed Text Templates are a great tool for your toolbox. Hope to see you use the best kept secret in Redmond.
Have a great day,
Just a grain of sand on the worlds beaches.