Code Generation with Visual Studio Templates


Visual Studio Templates is an extensible system of project and project item templates included in Visual Studio 2005 and 2008. A large number of predefined templates is installed out of the box. Screenshot on the right shows the list of C# project item templates installed with Visual Studio 2008 Professional. You can quickly create new templates for individual project items and entire projects using Export Template wizard. Matt Milner’s gives a good overview of Visual Studio Templates in this article published by MSDN magazine in 2006. Dylan Miles published a video on MSDN that walks you through the process of creating project and item templates using Export Template wizard.

Visual Studio Templates complement T4 Text Templates by allowing you to quickly generate simple boilerplate code for repetitive tasks, such as creating View, Controller and Presenter classes used in MVP and MVC patterns. T4 text templates are appropriate for more complex code generation, which requires synchronization of multiple source code files, such as generating CRUD stored procedures for a database table. Visual Studio Templates are easier to create than T4 templates and more appropriate when overhead of T4 complexity is too big compared for code that needs to be generated. Unlike T4, Visual Studio Templates can generate multiple files from a single template item.

Template Syntax

Visual Studio Templates provide a simple code generation mechanism in the form of template parameters. Here is an extract from the built-in Class template:

using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ == 3.5)using System.Linq;
$endif$using System.Text;

namespace $rootnamespace$
{
    class $safeitemrootname$
    {
    }
}

When generating actual file that will be added to the project, Visual Studio replaces $rootnamespace$ parameter with the default project namespace combined with the project folder to which new class is being added. $safeitemname$ template parameter is replaced with a valid programmatic identifier generated from the original file name by removing extension and replacing spaces with underscores. For example, if you add a new class called "1 Class.cs" to a folder called "Folder 1" in a C# project, Visual Studio will generate the following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication4.Folder_1
{
    class _1_Class
    {
    }
}

Template Structure

Visual Studio Template StructureBuilt-in project and project item templates are installed to <Program Files>\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates and C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates folders. Visual Studio looks for custom templates created by developers in the <user profile>\My Documents\Visual Studio <version>\Templates folder. A typical Visual Studio Template is a ZIP archive that contains a .vstemplate file, an optional icon file and one or more template files.

VSTEMPLATE file

This file provides information to Visual Studio on how to display the template in the Add New Item dialog and what to do when user adds this item to the project. For example:

<VSTemplate Version="2.0.0" Type="Item"
  xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
  <TemplateData>
    <DefaultName>Class.tt</DefaultName>
    <Name>Class Template</Name>
    <Description>A text template for generating a C# class.</Description>
    <ProjectType>CSharp</ProjectType>
    <Icon>TextTemplate.ico</Icon>
  </TemplateData>
  <TemplateContent>
    <References />
    <ProjectItem ReplaceParameters="true" TargetFileName="$fileinputname$.tt">
      Class.tt
    </ProjectItem>
  </TemplateContent>
</VSTemplate>

Name, Description and Icon elements define how this project item will appear in the Add New Item dialog. DefaultName element defines a file name Visual Studio will suggest when user selects this template in the Add New Item dialog. ProjectType element determines for which types of projects this template will be available. Template in this example will be available only in C# projects.

References element allows to define additional references (if any) that Visual Studio will add to the project when this template is selected.

ProjectItem element defines a file that will be added to the current project when user selects this template. Notice that ReplaceParameters parameter is set to true. This enables parameter substitution in the template file. You can have more than one ProjectItem element if you need to add multiple files. For example, the built-in Form template (Windows Forms), includes two ProjectItem elements (Form.cs and Form.Designer.cs).

Template File

Template file is, well, a template of the actual file that will be added to the project when user selects this template in Add New Item dialog. The following .tt file is a Visual Studio Template of an actual T4 .tt template that will be added to the project.

<#
// $itemname$.tt
// Copyright © $year$ $registeredorganization$
//
// For more information and examples of text templates visit
// http://www.olegsych.com/2007/12/text-template-transformation-toolkit
#>
<#@ template language="C#" debug="True" hostspecific="True" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.IO" #>
// <autogenerated>
//   This file was generated using <#= Path.GetFileName(Host.TemplateFile) #>.
//   Any changes made manually will be lost next time the file is regenerated.
// </autogenerated>
<#
    // To debug code generation, uncomment the following line
    // Debugger.Break();

    // TODO: Place template initialization code here.
#>
using System;

namespace $rootnamespace$
{
    public class $safeitemname$
    {
<#
    // TODO: Place template generation code here.
#>
    }
}
<#+
    // TODO: Place template class features here.
#>

This file uses $rootnamespace$, $safeitemname$ and other template parameters to customize the actual file that will be added to the project. Visual Studio will replace parameters with actual values when adding this file to the project.

Icon File

Visual Studio uses icon file from the ZIP archive when displaying the template in the Add New Item dialog. Default file used by Visual Studio Export Template wizard is different from the icon used by .tt files. Visual Studio Template in this example uses TextTemplate.ico which was installed by DSL toolkit in C:\Program Files\Common Files\Microsoft Shared\TextTemplating\1.2 folder.

Usage

Here are the steps you need to do to install and use use the T4 Class Template described in this article on your computer.

  • Download T4 class template using the link below.
  • Copy downloaded ZIP file (as is, don’t extract) to the following directory on your computer.

    <your profile>\My Documents\Visual Studio <version>\Templates\ItemTemplates\Visual C#

    where

    <your profile> is the folder where your profile is stored (C:\Documents and Settings\account on Windows XP or C:\Users\account on Windows Vista)

    <version> is the version of Visual Studio you are using (2005 or 2008).

  • Add New Class Template DialogCreate new or open existing C# project in Visual Studio
  • Select Project->Add New Item in Visual Studio main menu. You should see the template in the My Templates section of the Add New Item dialog.
  • Type in desired name for the new template and click Add.
  • Visual Studio will add a new .tt file with the specified name to your current project. Template text will be similar to this.
<#
// Class1.tt
// Copyright © 2008 Catapult International
//
// For more information and examples of text templates visit
// http://www.olegsych.com/2007/12/text-template-transformation-toolkit
#>
<#@ template language="C#" debug="True" hostspecific="True" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.IO" #>
// <autogenerated>
//   This file was generated using <#= Path.GetFileName(Host.TemplateFile) #>.
//   Any changes made manually will be lost next time the file is regenerated.
// </autogenerated>
<#
    // To debug code generation, uncomment the following line
    // Debugger.Break();

    // TODO: Place template initialization code here.
#>
using System;

namespace ConsoleApplication4
{
    public class Class1
    {
<#
    // TODO: Place template generation code here.
#>
    }
}
<#+
    // TODO: Place template class features here.
#>

Download

ClassTemplate.zip


Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.

Reader Comments

Is there a way to create a template (.tt) file that generates many .cs files?

Or…I want to use db template data to output a set of classes for each table in a specified database. What’s the best approach for this?

David C.

David,

It is possible to generate multiple .cs files from a single template. I think this is the right approach for what you described.

I will not be able to describe the solution in a short comment. This was actually the topic of an article I started working on several days ago. Please check back in a couple of days. I should be able to post it this weekend.

Oleg

Hi Oleg,
I enjoyed your presentation today at the Orlando Code Camp.
I am looking for your email address somewhere on this site, but do not see it. Please shoot me an email when you have a minute so I can reply to it.
-Greg

Hi, looking foward to the article you talked about in your last comment… I’m facing the same problem.

1) I want to create Class.cs template instead of Class.tt.
I tried many times, but failed to achieve my target. Can u please tell me how to do it ?

thanks

Pravesh,

Perhaps you could copy the standard class template included in Visual Studio and change it to fit your needs. The template is located in C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip.

Oleg

[…] An article about creating a VS template for T4 templates […]

You can generate code from Entity FRamewok Model with this tool:

http://www.codeplex.com/sfs

You can try please?

Hi Oleg,

I’ve been following your articles for some time now and have started to get accustomed to using T4 templates to generate code. I am especially engaged in a massive project whereby I’m bolting on a massive add-on to SubSonic 3 which provides caching for tables registered for SqlCacheDependency dramatically minimising database calls on tables with data that does not frequently change. On top of that, business objects are automatically customised with more useful properties which can be serialized the way you want using a custom serializer.

My problem is that my customizeable parameters are stored in the App.config as a configSection. Using T4, I can get all of the general Configuration settings using ConfigurationManager.OpenMappedExeconfiguration() but the configSections are not available. In my test console app, I can get the configuration settings and configSections using ConfigurationManager.OpenExeConfiguration() but it obviously won’t get access to the app.config in the T4 since there is no .exe file.

Have you encountered this kind of problem before or are you able to provide some insight on a solution?

…further to the above, my next idea is to read in the App.config as XML and deserialize the configSection into my custom config object which inherits from ConfigurationSection.

Hmmmm…..

Ashley,

I haven’t dealt with this particular problem myself. The approach with re-hydrating a ConfigurationSection sounds promising.

Oleg

Excellent articles on T4!

I don’t suppose you know if there is a T4 equivalent of CodeSmith’s SchemaExplorer. If there was something like this then T4 would be perfect.

Sphengle

T4 itself doesn’t have something similar to schema explorer in CodeSmith. However, you can use a number of existing .NET APIs to access database metadata. For example, if you are using SQL Server you can use SMO. Here is an example.

Hi Oleg,

Can we generate only cs file. This example is showed generating tt file.

Mehmet.

Mehmet,

Yes, you can. Simply make your ProjectItem a .cs file instead of a .tt.

Oleg

Hi Oleg,
when I change projectitem from to ,cs file created but $ parameters ($rootnamespace$,..) didn’t replaced, when I change projectitem from
Class.tt

to
Class.cs
,
visual studio (2010) display error message that could not find file …Class.cs

Mehmet

Hi Oleg, I have a simple question. Is it possible to write TextTemplate Files in the main instance and seeing the generated code in the debugging instance. I would like to see only the .cs files in my debugging instance. If I try, the model cannot be seen in the TT file (in the main instance).