T4 Toolbox: Support for Visual Studio 2010
As of version 9.10, T4 Toolbox now supports Visual Studio 2010 in addition to Visual Studio 2008. You can now create both traditional and preprocessed templates that utilize the advanced functionality the Toolbox offers to generate multiple output files, add them to different projects and more.
The set of project item templates has been extended to support preprocessed templates and generators. Here is what you will see when you add a new item to a Visual Basic project.
This list contains familiar project item templates, such as Template, Generator and Unit Test. Script is the project item template that was previously named File. It is a traditional .tt file that is meant to include other, partial .tt files such as Template and Generator. Hopefully the new name Script makes more sense than File.
The list of project item templates for Visual C# projects is similar and also includes ready-to-use code generators written in C#. It is the same with the exception of the Enum SQL View, which at this time works only in Visual Studio 2008.
Preprocessed Templates and Generators
Preprocessed Template and Preprocessed Generator project item templates, which are similar to the traditional Template and Generator respectively, were added take advantage of the new capability offered by Visual Studio 2010 to preprocess .tt files and compile T4-based code generators in .NET assemblies.
When you add a Preprocessed Template to your project, two files get created - a preprocessed .tt file and a partial .cs or .vb file similar to the ones below.
Template.tt (C#)
<#@ template language="C#" inherits="T4Toolbox.Template" #>
Template.partial.cs
namespace ClassLibrary1 { using System; using T4Toolbox; public partial class Template1 { protected override void Validate() { this.Warning("Template properties have not been validated"); } } }
Template.tt (Visual Basic)
<#@ template language="VB" inherits="T4Toolbox.Template" #>
Template.partial.vb
Imports T4Toolbox Partial Public Class Template1 Inherits Template Protected Overrides Sub Validate() Me.Warning("Template properties have not been validated") End Sub End Class
For preprocessed .tt files, T4 doesn’t generate actual output; instead it generates the code generation template itself. Here is a cleaned-up version of what you will see if you open the files generated by TextTemplatingFilePreprocessor.
Template.cs
namespace ClassLibrary1 { using System; using System.CodeDom.Compiler; #line 1 "C:\…\Template1.tt" [GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "10.0.0.0")] public partial class Template1 : T4Toolbox.Template { public override string TransformText() { return this.GenerationEnvironment.ToString(); } } #line default #line hidden }
Template.vb
Imports System Imports System.CodeDom.Compiler <GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "10.0.0.0")> _ Partial Public Class Template1 Inherits T4Toolbox.Template Public Overrides Function TransformText() As String Return Me.GenerationEnvironment.ToString End Function End Class
Together, Template and Template.partial files define a single class that descends from T4Toolbox.Template which I assume is already familiar to the reader. In a traditional T4 Toolbox Template, you would place all logic in a single .tt file, using a mix of text blocks and class feature blocks. With a preprocessed template, you will typically want to use the .tt file only for the logic that requires text templating. Non-templating logic, such as validation, properties, utility methods, etc. can be placed in the partial .cs/.vb file. This helps to reduce complexity of .tt files by isolating “presentation” code that requires text templating in its own file where it is not mixed with the class definition and model access code.
Despite of what their name implies, Preprocessed Generator project items are not .tt files. A traditional Generator is typically defined in a single class feature block of a .tt file, does not use any text templating features and uses one or more traditional Templates to generate output files. Similarly, a Preprocessed Generator is a simple .cs/.vb file that contains a Generator class definition and uses one or more Preprocessed Templates to generate output files. Here is what it looks like.
C#
namespace ClassLibrary1 { using System; using T4Toolbox; public class Generator1 : Generator { protected override void RunCore() { } protected override void Validate() { this.Warning("Generator properties have not been validated"); } } }
Visual Basic
Imports T4Toolbox Public Class Generator1 Inherits Generator Protected Overrides Sub RunCore() End Sub Protected Overrides Sub Validate() Me.Warning("Generator properties have not been validated") End Sub End Class
Just like in a traditional generator, you would typically define several properties and override RunCore and Validate methods.
T4Toolbox.Template Class Has a Breaking Change
In order to be compatible with template preprocessing in Visual Studio 2010, interface and implementation of the T4Toolbox.Template class had to change. TransformText method used to have a sealed implementation that called the abstract RenderCore method you had to override in the descendants. Now the TransformText method itself is abstract and serves the purpose of RenderCore which has been removed.
This is a breaking change for any existing traditional Template classes you may have. Here is an example of a Template implementation you had before.
C#
<#+ public class Template2 : Template { public override void RenderCore() { // Text blocks and code generation logic // … } } #>
Visual Basic
<#+ Public Class Template2 Inherits Template Public Overrides Sub RenderCore() ‘ Text blocks and code generation logic ‘ … End Sub End Class #>
And here is an example of a Template implementation you have to have now.
C#
<#+ public class Template2 : Template { public override string TransformText() { // Text blocks and code generation logic // … return this.GenerationEnvironment.ToString(); } } #>
Visual Basic
<#+ Public Class Template2 Inherits Template Public Overrides Function TransformText() As String ‘ Text blocks and code generation logic ‘ … Return Me.GenerationEnvironment.ToString() End Function End Class #>
In order to be compatible with the new version of T4 Toolbox, all existing Template implementations need to be modified to a) replace each RenderCore method override with a TransformText method override and b) return GenerationEnvironment.ToString() at the end of the method.
Template class now provides a new method called Transform, which returns a string and serves the same purpose as TransformText implementation served previously. Just like TransformText, this method is not intended to be called directly by code in your Generator or Script code, where you would normally call Render or RenderToFile. You would only call TransformText (and now Transform) method in unit testing code to validate code generation results without creating the output files. If you have any code that calls the now abstract TransformText method, change it to call the new Transform instead.
Introducing this breaking change was not an easy decision. It was necessary to “unseal” implementation of the TransformText in order to make T4 Toolbox compatible with TextTemplatingFilePreprocessor in Visual Studio 2010 which assumes that this method is abstract. Although it would have been possible to keep backward compatibility, it would result in confusing design and implementations working differently in traditional and preprocessed templates. Taking into consideration the effort required to maintain this going forward, we made a decision to go ahead and convert existing templates now and leave this change behind.
The changes required to upgrade existing code are straightforward. You can use the “Find in Files” feature in Visual Studio to find all instances of RenderCore methods that need to be converted to TransformText. This is a manual change as it requires you to add a return statement at the end of each method. Replacing calls to TransformText method with Transform can be safely accomplished using the “Find and Replace” across multiple files. Including code changes, running unit tests and resolving errors, this change took less than an hour with the existing code generators in T4 toolbox itself.
Under the Hood
In order to make T4 Toolbox compatible with both Visual Studio 2008 and Visual Studio 2010, we now have to separate assemblies: T4Toolbox.dll, a .NET 3.5 assembly which is used in Visual Studio 2008, and T4Toolbox.10.0.dll, a .NET 4.0 assembly which is used in Visual Studio 2010. Introducing a separate new binary was required because Microsoft.VisualStudio.TextTemplating assembly in Visual Studio 2010 has been renamed to Microsoft.VisualStudio.TextTemplating.10.0, which means that TextTransformation base class in Visual Studio 2010 is now physically different than the same class in Visual Studio 2008, forcing you to have separate binaries for descendants.
Producing a .NET 4.0 version of the T4Toolbox assembly required a complete overhaul of the build system. The project files had to be upgraded to Visual Studio 2010. To keep complexity under control and have a single set of project files, they had to be hacked to generate an assembly with different target .NET framework versions depending on build configuration. This had to be done directly in the project files because target framework is exposed as a project-level setting by Visual Studio 2010.
Microsoft SDC tasks don’t appear to support MSBuild 4.0 at this time and generation of Visual Studio project item templates had to be changed to use MSBuild extensions in the DSL SDK.
Because of these changes, the previously published instructions on how to get and compile T4 Toolbox source code are now incorrect. I will not go back and update these instructions until we have a release version of Visual Studio 2010 and things settle down a bit.



tangible T4 Editor for VS 2010 Beta 1 and later…
Just in case someone might be wondering - yes there is a tangible T4 Editor for VS2010 Beta. Please make sure you follow the steps here to install it. It is found in the VS Extension Manager.
Make sure that if you run VS as Admin or under XP that you do set the following checkboxes in the Tools->Options plus “Load Extensions from my local applications folder” – if you run VS as Admin.
More infos here:
http://tangibleengineering.blogspot.com/2009/05/tangible-t4-editor-now-listed-in-visual.html