Thursday, April 25, 2013

Visual Studio 2012 - Debug T4 Template

T4 is the acronym for Text Template Transformation Toolkit. People have always claimed T4 templates as a hidden gem from Microsoft. They are used by MVC and Entity Framework to generate code elements including controller and model classes. Visual Studio 2012 supports debugging T4 templates. They can be debugged at design time. In this post we are creating a very simple application in WPF to discuss how to use this in Visual Studio 2012. In the example we are adding a text template to add a file based on application settings in App.Config in a project. The template would introduce a new class ApplicationProperties. This would hold properties for each setting added in the settings section. For simplicity, let's keep the data type of all these properties as string.

For this example we need to add assembly reference for System.Configuration assembly. This would allow us reading the configuration settings from App.config file for the project.

Let's add a text template to the project. We name the template as

Now we add template code in file. We need to update the definition of the text template.

If your eyes just popped, put it back in its real place. Syntax Highlighting is still not supported in Visual Studio 2012. I know community has strong opinions about this and the absence of intellisense for template editor. Still not supported. Here I am using the Devart extension for T4 template. It adds syntax highlighting and intellisense for T4 templates.

The line numbers can be included by updating the setting for extension. The following is added to Options & Settings dialog. Checking the option would include the line numbers on a T4 editor.

The T4 template is added to the project definition [CSProj]. The resulting CS file is added to the item group for compilation. It is dependent on and automatically generated from the actual Text Template [TT] file at design time.

Let's update the definition of to include the code generation logic. It starts with adding directives for template, output, assembly and import directives. The rest of the code reads App.Config and generates properties for all the app settings.

The code uses Host.ResolvePath to get the path for App.Config. It then reads the content in an XmlDocument class. If there are no such settings it uses Error utility method defined in TextTemplatingFileGenerator custom tool. Saving the template file should result in the following error message.

Let's assume that this template was given to us and we need to determine what we need to do to fix this problem. Let' us put some breakpoints in the template code. Visual Studio supports inserting breakpoints and trace points in the template code as well. If we right click the template file in solution explorer, please notice the additional Debug T4 Template option available. Let's try to debug the text template to determine the cause of error message. Add some breakpoints to the template code. You can read about using break points & developer productivity in one of our previous discussion.

As we debug the template, we notice that the breakpoints are being hit. We can also notice that the debugging experience is integrated with other debugging windows available in Visual Studio including Quick Watch, Immediate and Locals windows.

In the previous posts we have been discussing about code map to visualize and debug code in Visual Studio 2012. The feature also seem to completely work with T4 template debugging. Since Code map is only supported for code visualization for C# and VB code, we wouldn't be able to navigate the code graphically to understand it better.

The Autos window seems to be broken in Visual Studio 2012.2 Ultimate. Please notice that it is empty even though the control has already passed through some variable declarations. It should have included document variable on the window to display its value.

The template editor still doesn't provide any refactoring support. So if you change a variable name, make sure that you propagate the changes to all the places in the code where it is being used. Although we see the error messages as reported by Error utility method in Errors List window but double clicking the error message wouldn't open the editor and navigate to the line where the error came from. It still shows the line number and template document name name in the errors list window, which is also not very useful as the line numbers are not from template document itself.

Anyhow, we realize that it needs the application settings to be defined in App.Config settings. Please notice the empty collection here.

We must remember that any error while running the custom tool on the template would not stop it at the line where the error is found but it continues and report all errors and warnings in the template. So the C# code file is still generated for application properties. Any error in the document also wouldn't fail the project build.

Let's update the App.Config to include some application setting entries. Here we are adding three properties AppTitle, ReleaseType and ReleaseVersion. They are assigned with their respective values.

As soon as we add these settings and run the custom tool from the context menu for T4 template from solution explorer, we can see the new properties being added to the generated class in solution explorer. We can also notice that the errors list is empty now.

The generated ApplicationProperties static class is also updated to include the new properties. Now as we add or update a setting in App.Config, a new property is automatically added to the generated class as the tool is run.

We can also run Custom tool from Project Menu. The following menu is available if we have a template selected in Solution Explorer.

We don't need to run each template individually. We can run the custom tools for all the templates in a solution. We need to add build toolbar in Visual Studio 2012 and use the following toolbar button to run these transformations.

There used to be this option in Visual Studio 2010 which is added when there is a T4 template added to a project in the solution opened in the Visual Studio editor. I can't seem to find the option in Visual Studio 2012.

Let's update our example Application's Main window to use the properties generated from the class generated from T4 template. Here we are using AppTitle, ReleaseType and ReleaseVersion as included in App.Config.

The application builds fine. The MainWindow appears on the screen being the startup window for the application. We can verify that all the values match as we declared them in App.Config.

Download Code

No comments: