Create Your Own Project Item Templates in VS 2005

Visual Studio supports extensibility in a couple of ways. One way is to implement the IExtensibility2 interface; another is to implement the IDTWizard interface. An existing IDTWizard is contained in the VsWizard.dll. This wizard supports project items and project templates, permitting you to create a new project (like a console application). You also can use the VsWizard.dll wizard to implement your own templates.

In prior versions of VS.NET, you had to define a template file, modify some common script files (common.js and default.js), add some line items to a file named template.inf, create a wizard launch (.vsz) file, and create a VSDir file that indicated where the template was located, what it was called, and how to show it in the Add New Items dialog (or related dialogs). Visual Studio 2005 builds on the flexibility of XML, condensing this process and making it significantly quicker and easier.

This article demonstrates how to create your own templates in VS 2005. Specifically, it shows you how to create a typed collection project item template.

Create a Template Metadata File

Because templates are still based on VsWizard.dll, the XML metadata file needs some of the same values that were added to the older template-style elements. Fortunately, they are all contained in one file with a .vstemplate extension and described as XML. All you need to create a project item template is a .vstemplate file and a code file with optional replaceable parameters.

Listing 1 contains the .vstemplate for your typed collection. A brief description of significant elements follows the listing.

Listing 1: A project item template’s .vstemplate file.

<VSTemplate Version="1.1.0" Type="Item">
   <TemplateData>
      <Name>
         <String>Typed Collection</String>
      </Name>
      <Description>
         <String>A strongly typed collection</String>
      </Description>
      <Icon>
         <Package GUID="{164B10B9-B200-11D0-8C61-00A0C91E29D5}"
                  ID="4556"/>
      </Icon>
      <ProjectType>
         <Languages>
            <Language>VisualBasic</Language>
         </Languages>
      </ProjectType>
      <SortOrder>20</SortOrder>
      <DefaultName>Collection.vb</DefaultName>
   </TemplateData>
   <TemplateContent>
      <ProjectItem>
         <SourceFile>Class1.vb</SourceFile>
         <ReplaceParameters>true</ReplaceParameters>
      </ProjectItem>
   </TemplateContent>
</VSTemplate>

The template file is named TypedCollectionTemplate.vstemplate. The elements are dictated by the wizard, which didn’t use elements such as tags for assembly references but did use the following elements:

  • VSTemplate indicates that the contents are for a template.
  • The TemplateData tag replaces the elements you used to place in the VSDir file, including a name, description, and language. (The icon used is an existing icon defined for a pre-installed VS 2005 template. You can add an icon literal path or a resource identifier for a known icon.)
  • The TemplateContent element indicates the element type—in this example, a project item—and the name of the source file that contains the template code.
  • The ReplaceParameters tag indicates that the associated source file contains pre-defined replaceable parameters.

Jason Kemp published an article that is a good source for some additional information. His article includes examples of assembly references, GUIDs for existing elements like icons, and an interesting example of a NUnit template. For more information on typed collections, see my previous article, and for more on old-style templates see this one.

Create a Codefile

The code file is straightforward. A typed collection is a class that inherits from System.Collections.CollectionBase (or System.Collections.ReadOnlyCollectionBase for a read-only collection) and contains an Add method and an indexer. The indexer returns the collected type and permits you to treat the typed collection like an array of the collected type. Listing 2 contains the implementation of the template file.

Listing 2: An Implementation of a Template Typed Collection

Imports System
Imports System.Collections

Public Class $safeitemrootname$Collection
   Inherits CollectionBase

   Default Public Property Item(ByVal index As Integer) _
           As $safeitemrootname$
      Get
         return CType(List(index), $safeitemrootname$)
      End Get
      Set(ByVal value As $safeitemrootname$)
         List(index) = value
      End Set
   End Property

   Public Function Add(value as $safeitemrootname$) As Integer
      Return List.Add(value)
   End Function

End Class

The token $safeitemrootname$ represents a known replaceable parameter. The wizard will replace this token with the name you enter in the Add New Item dialog. I suffixed the class name with the Collection word, which will distinguish the class name from the type returned. To ensure that the return type reflects the type maintained by the collection, use the name of the collected type in the Add New Item dialog or modify this bit of code after the template is created.

One current drawback to templates is the lack of documentation of known tokens. This is an oversight that I hope is corrected before Whidbey ships.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read