T4 Toolbox for Visual Studio 2012


Beta version of T4 Toolbox for Visual Studio 2012 is now available from the Visual Studio Gallery. You can install it from Visual Studio itself, using the Extension Manager. Simply select TOOLS, Extensions and Updates from the main menu; search the Visual Studio Gallery for T4 Toolbox and click Download.

image

Once the T4 Toolbox package installed, you can find T4 Toolbox project item templates in the Add New Item dialog of Visual Studio for C# and Visual Basic projects.

image

Changes in this version

This release of T4 Toolbox is significantly different than the previous version for Visual Studio 2010 and 2008. It was rebuilt from the ground up to take advantage of new capabilities of Visual Studio 2012 and Text Templating Transformation Toolkit.

VSIX package

The most obvious benefit is ability to deliver it as a VSIX package via the Extension Manager instead of an MSI installer. Instead of having to check for and download updates manually and wait for several long minutes for installation to complete, you will get automatic update notifications from Visual Studio and can update the package in just a few seconds. Admittedly, packaging T4 Toolbox as a VSIX alleviates even more pain on the development side, as it finally allows me to reduce the steps required to configure development environment to simply getting latest from source control and hitting F5. For both of these reasons, VSIX packaging will allow much more rapid delivery of the T4 Toolbox updates going forward.

No ready-to-use code generators

T4 Toolbox for Visual Studio 2012 does not include ready-to-use code generators. LINQ to SQL, SQL Enum, AzMan,  and other generators that were shipped with the previous version are no longer included. This decision was based on several factors. Some of these code generators became obsolete with the release of new frameworks and would be a waste of time to move forward. Dropping them, at least for the time being, also allows me to concentrate on improving the tools, and quite frankly, makes this release and the ongoing development feasible. I also think that NuGet packages are a better way to deliver T4 templates than VSIX. If you need to use any of the legacy code generators with Visual Studio 2012 I will do my best to support your effort to upgrade them on CodePlex.

No ready-to-use directive processors

T4 Toolbox for Visual Studio 2012 does not include any directive processors you can directly use in your templates. Directive processors are difficult to develop and maintain. They generate code generation code and have to be implemented using CodeDOM. They are also harder to use than templates because code they generate is invisible to you by default. In addition, the VolatileAssembly is no longer necessary because in Visual Studio 2012 the assembly directive shadow-copies the assembly files before loading them. The Xsd directive was a simple convenience wrapper for functionality provided by the xsd.exe command line utility. Most XML schemas are relatively static and you can use the utility to generate the XML serialization classes and include them in your templates directly.

Going forward, I think that developing reusable templates is a simpler and better way to package code generation logic than directive processors. When support for multiple output languages is required, you can use CodeDOM in preprocessed templates. The only time you have to use the directive processors is when you need to change the transformation process itself. For example T4 Toolbox still relies on a directive processor in the T4Toolbox.tt include file to initialize the TransformationContext and save additional output files, however you shouldn’t use this directive processors in your code.

No runtime templates

This required creating a separate Extension SDK VSIX package and didn’t make the first release. Let me know if you are actively using the runtime (a.k.a. preprocessed) templates with T4 Toolbox today.

API Changes

The original version of the T4 Toolbox was developed with the assumption that code generation is always performed at design time, when you save a template file or Run Custom Tool from the Solution Explorer. Since then, T4 gained better MSBuild support and many developers want to perform code generation at build time or both build and design time. In order to allow supporting this functionality in the future, the T4 Toolbox API was changed to remove direct dependency on Visual Studio API and be consistent with the MSBuild API.

TransformationContext

This class now fully implements the Singleton pattern consistently with HttpContext and other similar classes in the .NET framework. Instead of multiple static properties, like Transformation and Host it defines a single property called Current which can be used to access instance properties of the singleton object. So instead of accessing transformation host via TransformationContext.Host, you now have to access it via TransformationContext.Current.Host.

DTE, Project, ProjectItem, DefaultNamespace and RootNamespace properties are no longer available. They had internal dependencies on the Visual Studio APIs and were not forward compatible with MSBuild. However, TransformationContext now implements the IServiceProvider interface and you can use the new GetService method to access the same information like so.

<#@ template language="C#" debug="True" #>
<#@ output extension="txt" #>
<#@ include file="T4Toolbox.tt" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name="Microsoft.VisualStudio.Shell.11.0" #>
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="Microsoft.VisualStudio.Shell" #>
<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>
<#
// Get DTE
var dte = (DTE)TransformationContext.Current.GetService(typeof(DTE));

// Get ProjectItem representing the template file
ProjectItem projectItem = dte.Solution.FindProjectItem(TransformationContext.Current.Host.TemplateFile);

// Get the Project of the template file
Project project = projectItem.ContainingProject;

// Get the root namespace of the project
var rootNamespace = (string)project.Properties.Item("RootNamespace").Value;
this.WriteLine(rootNamespace);

// Get the default namespace of the project item
var vsSolution = (IVsSolution)TransformationContext.Current.GetService(typeof(SVsSolution));
IVsHierarchy vsHierarchy;
ErrorHandler.ThrowOnFailure(vsSolution.GetProjectOfUniqueName(project.FullName, out vsHierarchy));
uint projectItemId;
ErrorHandler.ThrowOnFailure(vsHierarchy.ParseCanonicalName(projectItem.FileNames[1], out projectItemId));
object defaultNamespace;
ErrorHandler.ThrowOnFailure(vsHierarchy.GetProperty(projectItemId, (int)VsHierarchyPropID.DefaultNamespace, out defaultNamespace));
this.WriteLine((string)defaultNamespace);
#>
OutputItem

The old OutputInfo class has been updated for consistency with MSBuild’s ProjectItem class. It has been renamed to OutputItem. Its BuildAction property was renamed to ItemType and its BuildProperties property was renamed to Metadata.

Roadmap

Going forward I want to take the T4 Toolbox the point where it provides first-class developer experience for working with text templates. This includes adding some of the missing features that didn’t make the first cut, like unit testing as well as adding new features, like build-time code generation, support for additional project types, namely SQLDB, and Visual Studio language service with colorized syntax and IntelliSense.

Previous Articles

ASP.NET Dynamic Data Unleashed


.Config File Transformation


Understanding ASP.NET Dynamic Data: Entity Templates


Extending ASP.NET Dynamic Data: Filtering with Joins


Understanding ASP.NET Dynamic Data: Filter Templates


MSDN Radio: Code Generation with T4 and Visual Studio 2010


Understanding T4: <#@ parameter #> directive


Understanding T4: MSBuild Integration


T4 Tutorial: Integrating Generated Files in Visual Studio Projects


Welcome

Thank you for taking the time to visit my site! If you are looking for information about T4, this article would be a good place to start. For information about ASP.NET Dynamic Data, my book would be a good place to start.

See you around!