Visual Studio 2013 Preview has been out for a while now so I thought I should announce the new goodies in the product for T4 this time around. As the T4 engine is fairly mature now we focused on a couple of scenarios that have been blocked or tricky for customers. I’m sure you’ll agree they are good ones.

1. Enable fine-grained template reuse with a new ‘once’ option on the <#@ include #> directive.

This feature makes it really easy to build up a library of reusable T4 snippets that you can include at will without worrying that some other snippet has already included them.  For example, I’ve now got a library of very fine-grained snippets that deal with template processing and C# generation.  In turn, these are used by some more task-specific utilities such as generating exceptions, which I can then use from any more application-specific template.  You can see in this dependency graph that my indentation helpers are used all over the place.  Now I don’t have to worry about clashes.

Dependencies between template snippets.

Customers ask me a lot about strategies for building reusable template libraries and the ‘once’ feature is the last major unblocker to a smooth experience for big libraries.  This feature works regardless of the host in use.  Here’s the syntax:

<#@ include file=“myinterestingsnippet.t4” once=”true” #>

2. Enable project-relative assembly references and includes across IDE and msbuild.

Until now, it’s been awkward to create templates that reference assemblies from standard project-relative directories and then transform them in both the IDE and from msbuild.  Typically it required environment variables, which most people hate!  We’ve fixed that with this feature.  You can now use project properties with include and assembly directives.  This feature works in the standard IDE host and in the msbuild host.  Here’s an example – imagine we have some helper code in an assembly called myLib.dll stored in a standard ‘libs’ directory.  Something magnificent, like this:

namespace MyLib
{
    public static class MyClass
    {
        public static string MyMethod()
        {
            return "World";
        }
    }
}

 

Now let’s use that helper from a template – in the IDE we could use macros like $(SolutionDir), but those don’t work in msbuild, so we’ll use a project variable instead:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="$(libDir)\MyLib.dll" #>
<#@ output extension=".txt" #>
Hello <#= MyLib.MyClass.MyMethod() #>

Of course, we’ll need to define the variable in our project file by adding a snippet like this:

<PropertyGroup>
    <libDir>$(MSBuildProjectDirectory)\..\libs</libDir>
</PropertyGroup>

 

At this point, the template should work in the IDE, but we need to take one more step before it works in msbuild.  We need to let the T4 msbuild task know which variables we’re using.  We add one final snippet to do that:  

  <ItemGroup>
    <T4ParameterValues Include="libDir">
      <Value>$(libDir)</Value>
    </T4ParameterValues>
  </ItemGroup>
 

3. Standard host used in ASP.Net scaffolding

This isn’t strictly a T4 feature, but it’s great news.  The very cool new ASP.Net scaffolding feature uses the standard VS T4 host, so you can use the full power of T4, and any include libraries you have when building scaffolding templates.

 

4. Tidy up after very spendy templates with CleanupBehavior directive.

Sometimes templates get big.  Or crufty. Or both. Or they load a bajillion assemblies to do their work.  This can bloat up your IDE’s memory footprint or lock assemblies in memory.  Now there’s a great big hammer to solve this problem.  Add the following line to your template and the appdomain it runs in will get blown away after every run. 

<#@ CleanupBehavior processor="T4VSHost" CleanupAfterProcessingtemplate="true" #>

This defeat’s T4’s normal caching behavior, so it slows things down a bit, but you get a spangly clean IDE every time.  This one only runs in the VS IDE host.

 

5. A bunch of small bugs, but that goes without saying.

Enjoy the release.