If you use Visual Studio, then you’ve probably crossed path with the Text Template Transformation Toolkit (or T4). For those who aren’t familiar with it, it’s a fairly straight-forward templating engine built into Visual Studio. The recent work on ASP.NET Core to enable cross-plaform web development, got me wondered what T4 might look like in this enviroment. Last weekend, I started hacking on Bricelam.TextTemplating, a T4 implementation for ASP.NET Core.

Writing

You write templates the same way as before. For example, the following VersionGenerator.tt file could be used to generate a C# file containing an AssemblyFileVersion attribute.

<#
    var version = GenerateVersion(
        major: 1,
        minor: 0,
        epoch: new DateTime(2000, 1, 1));
#>
using System.Reflection;

[assembly: AssemblyFileVersion("<#= version #>")]
<#+
    Version GenerateVersion(int major, int minor, DateTime epoch)
    {
        var now = DateTime.UtcNow;
        var today = new DateTime(now.Year, now.Month, now.Day);

        var build = (int)(today - epoch).TotalDays;
        var revision = (int)(now - today).TotalSeconds / 2;

        return new Version(major, minor, build, revision);
    }
#>

Transforming

To transform a template, you’ll need to add the following to your project.json file.

{
    "dependencies": {
        "Bricelam.TextTemplating": "1.0.0-*"
    },
    "commands": {
        "t4": "Bricelam.TextTemplating"
    }
}

Design-Time

To transform a template at design-time, use the following command.

k t4

This will produce a VersionGenerator.cs file with contents similar to the following.

using System.Reflection;

[assembly: AssemblyFileVersion("1.0.5548.41276")]

Build-time

If you want to run the transform every time you build, add the following to your project.json file.

{
    "scripts": {
        "prebuild": [
            "dnx project.json t4"
        ]
    }
}

Runtime

To create a runtime (or preprocessed) template, use the following command.

k t4 --preprocess

This will generate a VersionGenerator class that you can use run the transform at runtime. Use it with code similar to the following.

var template = new VersionGenerator();
var output = template.TransformText();

Console.WriteLine(output);

As a Service

You can also transform arbitrary templates at runtime without preprocessing them using the ITextTemplating service. Here is some code demonstrating how to do that.

var services = new ServiceCollection()
    .AddTextTemplating()
    .BuildServiceProvider();

var textTemplating = services.GetService<ITextTemplating>();

var template = "Today is: <#= DateTime.Today.ToString(\"D\") #>";
var output = textTemplating.ProcessTemplate(template);

Console.WriteLine(output);

A Work In Progress

Like I said, this is just the result of a weekend of coding. There are plenty of bugs and missing features. Just look at all the issues!

Like it? Hate it? Let me know.

Happy templating.