Visual Studio custom project and item templates

Creating a new project or an item in Visual Studio typically requires choosing one of the predefined project or item templates. They provide a basic framework and a good starting point for a new development. Most developers are very familiar with these templates. What is less known is that it is possible to create custom project and item templates. How do we create a template? How do we install it? Those are the two topics we are going to visit.
I have found custom templates to be useful when creating items with similar functionality. Web pages are prime examples. Common markup, layout, and code-behind logic may be defined in a template.
In the example below I have created a web page that we will later use to generate a template.
Page markup

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MyTemplateWebPage.aspx.cs" Inherits="Test.MyTemplateWebPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div>
        </div>
        <div>
            <asp:Button ID="btnSubmit" runat="server" Text="Submit" 
                onclick="OnButton_Click" />
            <asp:Button ID="btnCancel"
                runat="server" Text="Cancel" onclick="OnButton_Click" />
        </div>
    </div>
    </form>
</body>
</html>

Page code-behind

using System;
namespace Test
{
    public partial class MyTemplateWebPage : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (!IsPostBack)
                {
                    // Do something. Initialize controls?
                }
            }
            catch (Exception ex)
            {
                // Handle exception
            }
        }
        protected void OnButton_Click(object sender, EventArgs e)
        {
            try
            {
                // Do something
            }
            catch (Exception ex)
            {
                // Handle exception
            }
        }
    }
}

The page contains two buttons, Submit and Cancel. Both buttons have the common OnButton_Click event hanlder. When a user clicks the button, it triggers an action implemented in the event handler. Therefore, there is an exception handling block in the event handler. The Page_Load method also contains the exception handling block since it is the location where the input is received and the page controls are initialized. Checking for PostBack in the Page_Load method is another common operation across web pages which makes it a reasonable template candidate.
Our example defines the basic page skeleton which as a template, gives a developer a head start when creating a new web page. Not only does it save the development time, but also reminds the developer to follow certain best practices and guidelines.

Creating a template
The first step to creating a template is creating a source item or a project in a VS solution. In our example we will concentrate on the item only. Once we have defined our future template we can proceed with template creation by clicking File -> Export Template

The wizard dialog opens up and prompts us to select the template type. As mentioned earlier, there are project and item templates types. We will select the Item template. We also need to select the project from the drop down list that contains the source for our template.

Clicking the Next button presents the dialog where we need to select all the items that will be included in the template. Note that the item template may consist of multiple items such as aspx , css, ico, or any other file type.

On the next wizard screen we need to select the references to be included in the template.

Clicking the Next button opens the last wizard dialog. On this screen, we describe the template by giving it a unique name and description. The template can also have an icon and a preview image. The Icon Image makes the template look more professional and helps identify the template in the Add New Item dialog. The Preview Image seems redundant in my opinion. The Output location, read only text box, specifies the location where the template file will be stored upon generation. If you look carefully, you will notice that the template is a zip archive. It will contain all the items we have selected in the export template wizard. The Automatically import the template into Visual Studio option is useful if we plan to use the template on the same machine where we created the template. If selected, the template zip file would be copied to the VS template location which is by default C:\Users\Username\Documents\Visual Studio 2010\Templates. The location can be modified by going to Options -> Projects and Solutions -> General.

Clicking the Finish button will generate the template and store it in the location mentioned earlier. If we go to the location and open the zip file we will see all the files necessary to support our selections.

There is one additional file (MyTemplate.vstemplate) with a distinct vstemplate extension. It is a template definition file in xml format. There are many options that we can manually modify in the text editor. I am not going to cover them all, since they can all be found on MSDN. I will only point out the ones I found to be most useful.
ProjectType – The category in Add New Item dialog.
The template supports parameters which make the template instantiations more dynamic. The parameter names in the code are replaced with their values that were initialized in the export template wizard.
For instance, in our case, we have created a template from a class. When a developer creates an instance of the template, he will need to modify the class name and the namespace if he does not want to use the static template ones. Using parameters can automate this process. Anywhere in the code where we want to use the project namespace, we can use the $rootnamespace$ parameter. For a class name, we can use $fileinputname$ parameter. These are just the two most useful parameters, but there are many more available. In addition to the reserved parameters, we can also define the custom ones. They are initialized by IWizard extension implementation. The IWizard interface allows developers to create extensions to export template wizard in order to collect additional information and pass it as parameters to the template instance. Going back to our example. We could implement the IWizard interface using windows forms library to create a dialog which would allow the user to enter the web page title (or any other info) during export template process and automatically have it added to the title section of the page markup.

Installing a template 
Installing a template in VS is a single step process. All template artifacts are packaged in a single zip archive. It consists of copying the zip file to the default custom template folder location (C:\Users\Username\Documents\Visual Studio 2010\Templates). Note that the folder has two subfolders, one for items appropriately called ItemTemplates and the other one for projects called ProjectTempalates. That is all there is to installing the template. It is available in VS right away. There is no need to restart VS.

Conclusion
The templates are one of the less known VS features and disproportionally underused in comparison to the functionality they provide. If implemented thoughtfully and maintained consistently they can make the development process more efficient. Templates provide the skeleton that forces developers to follow guidelines and best practices which produces more maintainable and less error prone code.

Leave a Reply

Your email address will not be published. Required fields are marked *