C# Corner

Define Your Own Item Templates

Take advantage of C#'s Item Templates to automate tasks that you find yourself having to perform on a regular basis.

TECHNOLOGY TOOLBOX: C#

Developers are lazy. I don't mean that in a bad way, but in the same way that a smart horse is a lazy horse. Developers just don't stand for repeating the same tasks without finding a way to automate them. I count myself among the lazy developers. I'm quite willing to spend time figuring out how to automate those repetitive tasks that I find myself doing often. Visual Studio provides enough extensibility points that I've made a new rule for myself: If I do the same task twice, I figure out how to automate it.

One of the most common ways to automate tasks is to create new class Item Templates in Visual Studio. In this article, I'll show you how to recognize when Item Templates are the best way to automate a task, how to create Item Templates, and how to install them. I'll also briefly touch on how to update the standard templates, if you need to change those.

You probably use the default Item Templates everyday: new class, new form, new control, and so on. If you do anything sophisticated, or your development shop has any form of standards, you likely need to make changes to the generated code immediately. Are those immediate changes repetitive? Do you make the same changes every time? If the answer to any of these questions is yes, you might be able to save time by creating a new Item Template.

My first Item Template added a copyright notice to the top of each class. Most customers I work with have some standard text they want in each source file. It's annoying to do extra work for each customer, such as adding that copyright notice every time. Of course, you can add snippets, or create a macro to add the copyright information to each file. But that's an extra step. A better approach is to create a new class template that contains the copyright information.

This is your first Item Template, so let's do it the easy way using Visual Studio's Export Template wizard, and then make some modifications by hand. Create a new class library project in Visual Studio called "Template One":

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

namespace TemplateOne
{
    public class Class1
    {
    }
}

All you need to add initially is the copyright notice. Add the extra comments at the beginning of the file to suit your standard and then save the file (see Listing 1).

You can learn the basics of creating Item Templates by leveraging Visual Studio's Export Template wizard. This wizard will save almost any code element you choose as an Item Template. Select Class1 to be saved as a template. Add all the standard references as part of the template in the Export Template Wizard. You'll get a warning displayed when you add System.Core and System.Xml.Linq because these assemblies are 3.5 specific, but you'll fix this error later. Next, pick an icon. I've made several versions of the copyright template, one for each of the customers I work with. I replace the logo in each of these templates with the logo for that customer. For the sample, I used the Visual Studio Magazine logo. There are a lot of templates and I find that creating a custom logo, even if your graphic design skills aren't great, can provide visual cues to help you find specific Item Templates quickly. Give your Item Template a name and a description on the final page of the wizard (see Figure 1).

That's it, you now have a simple template that creates a class similar to the VS.NET class template, but with your standard copyright information.

Modify the Exported Template
Note that I said the simple template is similar to the VS.NET class template. The template language is quite a bit richer than what the default wizard uses to create items. The Export Template wizard is a good place to start, and it provides some good procedures to use, but you should make some changes to the exported template before you use it in a production app.

The wizard puts two copies of your Item Template on your machine. Both copies are under your Documents\Visual Studio 2008 directory. One is under My Exported Templates. This directory will contain every template you ever create with the export template wizard. The other copy, the one Visual Studio reads, is under Templates\ItemTemplates. Be sure to unzip the copy in My Exported Templates so you can examine what the wizard creates for you. Visual Studio packages three files together in the template: class1.cs, _TemplateIcon.ico, and MyTemplate.vstemplate.

The first thing you should do is examine class1.cs. Remember the warning you received for including the System.Core and System.Xml.Linq assemblies in your using statements. The error was triggered because including these assemblies causes errors when you include your Item Template in a project that targets the .NET 2.0 or 3.0 Framework. The Item Templates installed with Visual Studio support macros that work around that limitation, but these aren't added when you export user-defined templates.

You can fix errors caused by including 3.5 namespaces by adding another macro in the template class, class1.cs. Wrap the using statement in an if conditional that checks the target framework:

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

The macro language is a bit ugly in terms of the whitespace. If you leave extra CR/LF pairs in the macro, those blank lines show up in your new class when you create a new item from your template. The macro processing preserves any formatting around macro keys in case you've used macros in logic where whitespace and line breaks could be significant. For that reason, you need to write your macros such that the macro processing produces the code formatted for your style guidelines. You can also remove the public access modifier from the class. My own preference is to use the default access (internal) and make it an explicit developer choice to create a public class.

There's nothing magical about the name of the source file. Save your changes and rename the file to something that makes more sense to you. Then do the same with the icon file, giving it a name that matches its source.

Next, you need to edit the vstemplate file. This is an XML file that describes how Visual Studio should process the template, as well as all the parts that make up the template itself.

Editing this file controls everything else in your Item Template. Before you do anything else, change the version attribute in the VSTemplate element from 2.0.0 to 3.0.0. The Visual Studio team added new capabilities to the macro language, but these new capabilities are only parsed in the 3.0.0 version of Item Templates. If you forget this change, the $if$ conditional you added to your .cs file won't be parsed, and the $if$, $endif$ will end up in your source code.

Begin by changing the template to reflect the filename changes you made earlier. Near the top of the file, you'll find the <Icon> element. Change that element to reflect the changed name of the icon file:

<Icon>vsm.ico</Icon> 

Next, you need to change the ProjectItem element. This is a bit more complicated than what we've discussed so far. The text for the element is the name of the .cs file that contains the item. There's also an attribute that you need to modify. The TargetFileName attribute contains the name of the file as it should be added to your project. Normally, it would be something like class1.cs. You can change that to meet your project standards (for example, MyCompanyNameClass1.cs). You control the target file name through the DefaultName element later. Leave it as it is now. Visual Studio adds numeric constants to the file name each time you insert the item in a project. The final version of the Project element looks like this:

<ProjectItem SubType="Code" 
   TargetFileName="$fileinputname$.cs" 
ReplaceParameters="true">
SRTClass.cs
</ProjectItem>

You'll want to edit three more elements near the top of the file: the DefaultName element, the Name element, and the Description element. The DefaultName element gives the name the file should be given when that element gets inserted into your project. Remember that, by default, the class name and the file name share the same base class. This element can control the class name for the same reason.

You can change the Name element to whatever you want displayed in the Insert Item dialog. You can also update the Description element in this file (see Listing 2). Now copy the file to the Templates directory, or the VisualC# subdirectory under templates, so you can begin using it. The new Item Template shows up at the bottom of the "My Installed Templates" list when you go to Insert Item on any C# project.

One of the best ways to learn about the capabilities of these Item Templates is to look at the Item Templates that are installed with Visual Studio. These are all simple .ZIP files, and you can copy them, open them up, and look at them for inspiration when building your own templates. You can modify them in place and change their behavior, but I prefer making new versions for my own extensions. That way, the original behavior is still in place.

This examination of the Visual Studio Item Templates should provide some good ideas on how to go about automating common tasks. You can also create your own Interface Template using this article's sample class as a model. The cool part about the techniques demonstrated is just how easy they are to take advantage of, and how much mileage you can get from them in terms of automating tasks you need to do with any regularity.

About the Author

Bill Wagner, author of Effective C#, has been a commercial software developer for the past 20 years. He is a Microsoft Regional Director and a Visual C# MVP. His interests include the C# language, the .NET Framework and software design. Reach Bill at [email protected].

comments powered by Disqus

Featured

Subscribe on YouTube