Blog

Running T4 Templates from a custom program

December 28th, 2012

Example code can be found here: 

https://github.com/MikeLarned/Demo-RunTimeTextTemplate.git

Background

Most projects have some level of repetitive code that comes from the architecture or structure of an application.  Taking ASP.NET MVC as an example,  apps have controllers, views and (potentially) services that all have some similarity in structure with varying methods and underlying class names.   Scaffolding these portions of an application can save time, reduce human errors and be used help maintain a particular structure.  In Visual Studio, ASP.NET MVC comes with a pre built set of T4 scaffolding for generating common code.

We had a need to generate scaffolding based on T4 templates, but from a custom app that would be ran outside of Visual Studio.   Our team maintains a multitenant SaaS starter kit called Protolith that is built on the ASP.NET MVC Web API and Backbone.  The scaffolding requirements are quite a bit different for a Backbone based application consuming a RESTful API than the needs of a standard ASP.NET MVC app.  For example, our app has typical objects (entities –> services –> repository) exposed through an API, but then consumes the API all through Backbone based models, routers and views.   Our goal was to scaffold both the front and back end objects by providing meta data on the basic structure of the app. 

Scaffolding with T4 is not a silver bullet.  CRUD based screens often have little nuances and rules that are hard to scaffold, however scaffolding basic objects for CRUD gives us a solid starting point for new features. 

The problem with a normal T4 template, is that is tied to the Microsoft.VisualStudio.TextTemplating assembly, which basically translates that you need Visual Studio to run the template transformation.  The answer for our command line tool it to use preprocessed or runtime T4 templates.  You can checkout Oleg Sync’s blog for more information on the differences between traditional and preprocessed T4 templates.   (http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/)

The ‘Hello World’ of Preprocessed T4 Templates

I had a hard time finding the ‘Hello World’ of Runtime Text Templates usage in a custom application.  Often times, the simplest code provides a nice starting point for us to get going.  Below we will create a small app to generate an ‘Entity’.  For our starter kit, this will be the starting point for our code generation.

    1. In Visual Studio, create a new ConsoleApplication (the example code console app is called ExampleTemplateGenerator)
    2. Right click the Project file and select to ‘Add New Item’
    3. Make sure the Visual C# Items group is highlighted.  You should see two types of T4 templates in the list, Runtime Text Template and Text Template.  Select the Runtime Text Template and name it Entity.

      Image(5)[4]

    4. The entity template will have two fields to fill in data with, the assembly name and the entity name.  In Runtime Text templates, data is filled in by using a partial class that the T4 template can access at run time to perform the text generations.  Right click the project again, and add a new Class item called EntityData.cs.
    5. EntityData needs a constructor that takes two parameters (assembly name and entity name)  (Here we are using private backing fields, its a partial class and the template will have access to those fields).  The cs file we created will be called EntityData.cs, however the internal class will be a parital of Entity.  Below is the final code for EntityData.cs.

    6. Now that we have data for our T4 template, lets tell T4 how to consume that partial class.  Open up Entity.tt and add the following code:


      Here we use the private backing fields from EntityData.cs to fill in the assembly and entity name during code generation.

Generating Templates

Lets tell the console application to create an Entity with our custom entity name and assembly name.  The output from the transformation will be printed to the console.  At a later point we can output this to a file, or directly into our solution.  Update your Program.cs file Main method.

Note that the Entity class has two parameters for entity and assembly name that were defined in the partial class.  Running the program should output our scaffolded User entity to the console.

Image(6)