Printer Friendly Version      Send     
Click to Rate and Give Feedback
Related Articles
The goal of the ADO.NET Data Services Framework is to create a simple REST-based framework for exposing and consuming data-centric services easily.

By Elisa Flasko and Mike Flasko (August 2008)
We introduce you to the EDI functionality within BizTalk Server 2006 R2, illustrating schema creation, document mapping, EDI delivery and transmission, and exception handling.

By Mark Beckner (August 2008)
In this excerpt from his upcoming book, Laurence Moroney explains the basics of Silverlight animation and the animation tools available in Expression Blend.

By Lawrence Moroney (August 2008)
We build a Silverlight 2.0 application using the InkPresenter to let users annotate a pre-defined collection of images, perform handwriting recognition, and save the annotations and recognized text into a server-side database.

By Julia Lerman (August 2008)
More ...
Articles by this Author
Matt Milner addresses reader requests for information about safely sharing a persistence database across applications and using lesser-known parts of the framework such as ChannelManagerService.

By Matt Milner (August 2008)
When building workflows, you must consider the developer experience, available tools, long-term maintenance, and future versioning.

By Matt Milner (May 2008)
With the NET Framework 3.5, Windows Workflow Foundation can now truly be integrated with Windows Communication Foundation. This column describes how the integration works and how to make use of it effectively.

By Matt Milner (Launch 2008)
Matt Milner introduces the Windows Workflow Foundation (WF) communication architecture and covers sending data out of a workflow and submitting data to running workflow instances.

By Matt Milner (September 2007)
This month Matt Milner explains a critical component in the execution, persistence, and compensation of workflows.

By Matt Milner (June 2007)


By Matt Milner (March 2007)
This article covers the core components required for building custom activities in Windows Workflow Foundation.

By Matt Milner (December 2006)
More ...
Popular Articles
James Kovacs explains the dark side of tightly coupled architectures, why they're hard to test and how they limit adaptation. He then proposes a number of solutions.

By James Kovacs (March 2008)
Here we present a rundown of the various language paradigms of CLR-based languages via short language introductions and code samples.

By Joel Pobar (May 2008)
Learn how to create a workflow that uses InfoPath forms and other office documents for passing data to targeted activities and for use in Office documents.

By Rick Spiewak (June 2008)
See how to build a document-level Visual Studio Tools for Office customization and integrate it with a content type in SharePoint.

By Steve Fox (May 2008)
More ...
Read the Blog
One of the neat things about XAML is that you can not only declare your objects using an XML syntax, but that you can define transformations to rotate, move, and skew your objects. In the August 2008 issue of MSDN Magazine, in an article adapted from his upcoming book Introducing Microsoft Silverlight ...
Read more!
Microsoft has a long history of introducing new features to shipped products, often under the banner of Power Toys or Power Tools. In the August 2008 issue of MSDN Magazine, Brian Randell takes you on a tour of some useful tools for ...
Read more!
Designing software is often an exercise in managing complexity. You can take steps to limit the complexity of any given class by only assigning it a discrete set of responsibilities, applying a concept known as object role stereotypes. In the August 2008 issue of MSDN Magazine, Jeremy Miller explains ...
Read more!
When you evaluate any new technology, pattern, or strategy, you have to consider how that new piece of the puzzle is going to mesh with your existing application architecture. With the Entity Framework, integration is not a problem. In the July 2008 issue of MSDN Magazine, John Papa demonstrated ...
Read more!
Electronic Document Interchange (EDI) encompasses the largest share of real-world business-to-business commerce—nearly 90 percent of the current market—and is growing rapidly year over year. In the August 2008 issue of MSDN Magazine, Mark Beckner introduces ...
Read more!
Separation of presentation and data is not a new idea, but with the growing popularity of technologies such as AJAX and Silver­light, it has become much more prevalent. ADO.NET Data Services Framework began as a way to help developers looking to expose and consume data via services from their applications.. In the August 2008 issue of MSDN ...
Read more!
More ...
Visual Studio 2005
Create Reusable Project And Item Templates For Your Development Team
Matt Milner

This article discusses:
  • Consuming existing templates
  • Creating new project and item templates
  • Customizing templates through XML metadata
  • Extending the new project wizard
This article uses the following technologies:
Visual Studio 2005, XML
Over my years of working with clients on building Microsoft® .NET Framework-based applications, I have often heard a common feature request for Visual Studio® .NET: "It would be great if we could create our own project types and item types so that all developers in our organization would have access to them." Many orgs want to create shared templates for projects such as Web sites or for project items, such as a default Web page or forms. Visual Studio 2005 introduces a new model for defining templates and starter kits for projects and items that make this not only possible, but relatively simple. I'll take a look at how to consume, create, and customize these templates.
In the past, users have been able to create project or item templates, but it took a lot of inside knowledge of arcane text file formats, JavaScript files, and folder naming conventions, as well as a little bit of magic, to make it work. With the new model, a user can create a simple ZIP file of the items to be included in the template and an XML metadata file that describes the template and its contents. This new model supports creating item templates such as a Web page, a C# or Visual Basic® code file, or a configuration file. It also supports single-project templates like Web sites, class libraries, or smart client applications, as well as multiproject solutions. In fact, most of the built-in project and item templates that you use to create new solutions in Visual Studio 2005 are based on this same template mechanism.

Consuming an Existing Template
The easiest way to understand how these templates work is to first take a look at how to consume a template that has already been created. In Visual Studio 2005, you can configure the locations to search for templates, and these locations can use any Universal Naming Convention (UNC) path. In the Options dialog box, under the Projects and Solutions settings node, you can configure the user-specific locations to look for project or item templates (see Figure 1). The default values for these settings point to template folders in your My Documents folder. The templates included with Visual Studio 2005 are located under the Visual Studio installation directory and are included in the project setup dialog boxes by default.
Figure 1 Template Location Options 
By dropping a ZIP file with the appropriate metadata file in the user-configured template location, the new project or item template will appear in the respective dialog boxes. The sample code included with this article includes sample project item and project templates that can be copied into these directories for testing purposes. After adding the ZIP file, start Visual Studio 2005, choose File | New | Project, and notice that the new project template is included under the My Templates section of the dialog box (see Figure 2). Selecting this project template will create a new project with the items included in the ZIP file.
Figure 2 Your Templates Appear in the New Project Dialog Box 
There are several benefits gained by being able to consume templates in this way. First, because the user locations are configurable, development groups can define a file share on a common server where templates are deployed for the group. All developers in the group can configure their environment to look to that file share for templates. When a new template is deployed to the server by copying the ZIP file to the share, all developers immediately have access to it from within Visual Studio. After the initial deployment, changes to the template can be made in one place instead of having to be deployed to each developer's workstation.
In addition, because the template is used as a true template, it remains unchanged and can be used repeatedly to create new projects. This is a vast improvement over the old "copy and paste" approach where one developer would create a file or project and hand it off to another. Without careful management, the original was quickly lost and modified with no chance to get back to a known good configuration. Because the project and item template locations are configured independently, an organization can choose to have only project templates centralized and allow developers to create their own item templates.
In addition to templates, Visual Studio 2005 includes a starter kit concept. Starter kits enable broad consumption of samples through community sites from which templates can be downloaded. From the New Project dialog box, one of the options is Search Online Templates. Choosing this option allows you to search for starter kits online by keyword. When a starter kit is found, you can choose to download and install it into the appropriate directory so that you can then use it as a template for adding items or projects. As the name implies, starter kits are generally used as learning tools or samples to help convey knowledge or provide a starting point for larger projects.

Creating Templates
Consuming templates is a great start, but most developers will want to know how to create their own templates. Visual Studio 2005 makes it extremely easy to create your own templates right in the IDE. Once they are created, you have the ability to extend and change them.
The simplest type of template to create is an item template. To do so, simply open a project that includes the file you want to use as a template and then chooses File | Export Template to run the Export Template Wizard shown in Figure 3.
Figure 3 Exporting an Item Template 
The wizard will prompt you to indicate the item to export and any assembly references to include. Adding references allows you to ensure that assemblies your template depends on are included in the project when the item is added. For example, if an item template uses the System.Data.SqlXml assembly to access SQL Server XML functionality, it is important to make sure this assembly gets referenced by the project when the template is added. The references available to choose from in the wizard include the default assembly references for the current project type as well as any references that have been added to the current project before running the wizard.
In addition to the assembly references, the export wizard is intelligent enough to export resource files required by the item be exported. For example, if an ASP.NET Web page is the item being exported, the C# or Visual Basic codebehind file and resource file for that page will also get exported and included when the template is used to create new items. The wizard also edits these files to add placeholders for class names and namespaces so that when they are added to a new project they can be named differently and show up in the correct code namespace. For example, instead of having a class that's always named BusinessObjectClass when you add your template, the user can specify a name for the new code file, and this will be used as the name for the class in your template.
When the parameters have been selected for the item template—including a name, a description, and the icon to use when displaying the template—you have the option of installing the template. When exporting the template, it gets created in your My Documents\Visual Studio 2005\My Exported Templates folder. Templates in this folder are not included in the New Item or New Project dialog boxes by default. In order to make the template available for use, it must be installed by copying it to the configured directory for templates. Checking the box to install the template simply means that the ZIP file will get copied to the folder you configured for templates in addition to the exported templates folder.
Not installing the template allows you to edit the metadata directly or add other files to the ZIP file before installing the template into the appropriate folder. For example, if you created a Master Page template for use in Web sites, you might want to include a CSS file that includes the styles used on the Master Page to ensure that the styles used are also included when the Master Page template is selected. In this case, you would not want to install the template at this point until you have had a chance to add the stylesheet file to the ZIP file and update the metadata file to include the stylesheet when installing the template. I will look at the steps required to customize a template like this later in the article.
Creating a project template works in much the same way with the exception that assembly references are not needed as they are inferred from the current project configuration. The main difference between the project template and an item template is that a project template provides the means to create a new project, whereas the item template can only be added to an existing project. Both template types, however, allow for multiple items to be added to a project when the wizard is run.

Customizing Templates
As you can see, creating a project or item template has been made extremely simple in Visual Studio 2005. However, like many wizards, the default template created may not be exactly what you want. Fortunately, because the design of the templates involves a ZIP file and a metadata file, it is not difficult to extend a template with new features once it's created.
The template metadata file is an XML file that describes the template and indicates the files and resources to be included in with the project or item. A sample metadata file created by using the wizard to export an item template is shown in Figure 4.
The first thing to notice is the general structure of this metadata, which includes a root VSTemplate node and two child nodes: TemplateData and TemplateContent. The VSTemplate node simply acts as a wrapper for the other two items and indicates the type of the template. Because of the XML namespace declaration in the file, any developer editing this file in Visual Studio 2005 will automatically get IntelliSense® support for the items that are allowed, based on the schema for template files.
The TemplateData element contains information that is used to provide details about the template in the New Project or New Item dialog box. The name, description, and icon elements are all displayed directly in the dialog box as you would expect. The DefaultName element is used as the root of the default name provided for the new item or project. The ProjectType element indicates the type of project that the item can be included in and affects the location in the dialog box. The example shown in Figure 4 will cause this item template to be available only for C# Web projects.
Figure 5 shows some other optional elements that can be used in the TemplateData section of the metadata file, as well as options for the items already mentioned.
The TemplateContent element is where you define the files and references for your item template. The TemplateContent element references any assemblies to be included with the item or project and generally will not need to be edited since you can specify these in the export wizard.
Each item in the ZIP file that is to be included in the project is called out with a ProjectItem element. In addition to identifying the source files, the attributes of the ProjectItem element allow you to indicate whether an item has a subtype, whether parameters in the file should be replaced, and whether the target file name differs from the source file name. The subtype attribute can include values such as Form or Component, which provide Visual Studio with hints about how to display the item in the correct designer when it is opened.
Replacing parameters allows the New Item wizard to create namespaces, class names, and similar items dynamically so that the template is not entirely static. Without specifying true for this attribute, the template files will appear in the new project exactly as they are in the ZIP file.
The TargetFileName attribute allows you to specify either a constant or parameterized value for the file name as it should appear in the new project. This allows you to reuse a template file to create multiple instances of the item in the same project. For example, a class file could be added to the same project twice with different TargetFileName attributes. When the item is added, two new classes will be added to the project based on the same template file. Allowing for this type of reuse within the template makes it much easier to manage the files involved in creating a template.
When creating project templates, the process is very similar to that used for item templates, but there are a few slight differences in the metadata file. First, because this is a project, all ProjectItem elements are included under a Project element, which indicates the project file name and whether parameters should be replaced when naming the project file. An abbreviated project template file is shown in Figure 6.
Notice that in addition to the Project element that identifies the project information, this example also uses the Folder element to indicate that the ZIP file contains a folder containing the project items indicated. The folder will be included in the project structure when the template is used. The project template also provides different options for the TemplateData section to influence the user interaction with the New Project dialog box. These items are shown in Figure 7.
Web projects are configured in a slightly different manner as they use a different wizard for project creation. Instead of using a language for the project type such as Visual Basic and then a ProjectSubType such as Windows, a Web project uses Web as the project type, and the language as the ProjectSubType.

Templates for Multiple Projects
In addition to being able to configure a template for a single project, it is often useful to create an entire solution as a template or starting point. For example, a development group might not simply want a single Web project as the starting point for a new Web solution as they may want to include business object and data access projects. One resolution would be to create a template for each project and allow the developer to add each project they needed individually. However, a much simpler approach, and one that provides more consistency, is to create a template for the entire solution and give a developer all of the projects they need to get started.
Multi-project templates still involve only one ZIP file, but they include one master metadata file and an individual metadata file for each project in the solution. The project metadata files are no different than what has been discussed so far, but the solution template file now provides the template data to the wizard through the TemplateData element and its children and provides pointers to the other project metadata files through the TemplateContents element and its children. The abbreviated sample in Figure 8 shows a solution metadata file that includes three projects: a Web site, a business logic layer, and a data access layer.
Figure 9 Solution Folder 
Notice that the Type for the template is a ProjectGroup and that the template content is simply a collection of links to the other project templates. A friendly name can be given to the projects, and this is how they will be named in the Solution Explorer. The paths to the other projects are based on the folder structure of the items in the ZIP file. The ZIP file used with the example template metadata in Figure 8 would look something like Figure 9. Each project in the solution has its own folder and its own vstemplate metadata file, and the links in the example provide relative paths to the project template files based on the folder structure in the ZIP file.

Providing Guidance
In addition to providing templates, it is often helpful to provide guidance or extra information about how to use the template. One way to do this is to provide well-commented template code files, but this requires a user to dig through your template code to understand how to use it. Visual Studio 2005 templates provide a better mechanism for not only delivering the documentation your users will need, but for making sure they are presented with the documentation after adding an item or project from your template.
In both project and item templates, the ProjectItem element can have several attributes applied to it that allow for displaying items to the user. The OpenInEditor Boolean attribute allows a project item to be opened in the default editor based on the file type of that item. For example, an XML file included in your project and marked with OpenInEditor set to true will be opened in the XML editor. The OpenInWebBrowser attribute allows a text or HTML file to be opened in a Web browser window. This is an easy way to distribute help or guidance with your templates. Simply create an HTML file providing your guidance and include it in the template. Users will view your help file whenever they use your template so you can be sure they have the information they need to properly use your template files once installed.
In addition to having files open in the browser or editor windows, you can control the order in which the items appear when you have multiple items opening. You should use the OpenOrder attribute on the ProjectItem element in order to control the order of the displayed items in Visual Studio. The lower the number supplied for OpenOrder, the higher the priority and the closer to the front the item will be displayed.

Parameter Replacement
In many of the examples so far, parameter replacement has been used to allow for the dynamic creation of item and project names and namespaces. Parameter replacement involves using placeholders in the metadata file or in the included source files to indicate where a certain parameter value should be inserted. When you create a new item or project from a template, Visual Studio inserts actual values for the placeholders. There are several built-in parameters that can be used; it is also possible to add your own parameters to be passed to the wizard for replacement.
For parameter replacement to occur, the ReplaceParameters attribute must be set to true on either the Project element or the ProjectItem element. These are the two main locations where parameter replacement is used. When the wizard processes the project files and the included items, for each item where ReplaceParameters is set to true, the wizard searches through a dictionary of values to see if it has any known keys that match the parameters in the file. Parameters with a match are replaced with the stored values. Figure 10 shows the built-in parameters that are available to be used in metadata files and source files.
Custom parameters can also be added to the template and are then available in the item templates and metadata file as well. To add custom parameters, you add a CustomParameters section within the TemplateContent element of the metadata file. For each parameter you want to add, you can specify a CustomParameter element with a name and the value (see Figure 11). Name your values using the $parametername$ syntax in this file in order to use the same naming convention in the source files.

Extending the Wizard
If all the extensibility and parameter replacement is not enough to meet your needs and you really have to write some code to provide the dynamic data you need for your template, you can write a wizard extension and configure it in the template metadata. An example of when you might need this type of extension is a case where you have several items in a template and need to be able to include or exclude some at run time. With a wizard extension, you can augment the standard New Project or New Item wizard with your own code and make decisions about what items to include or exclude as well as adding dynamic custom parameters for replacement in the project files.
In order to create your own wizard extension, you need to create a .NET library project in your managed language of choice and add a reference to the Microsoft.VisualStudio.TemplateWizardInterface.dll and EnvDTE.dll assemblies. Create a class in your library project and implement the Microsoft.VisualStudio.TemplateWizardInterface.IWizard interface. The IWizard interface members are listed in the following code:
public interface IWizard
{
    void BeforeOpeningFile(EnvDTE.ProjectItem projectItem) ;
    void ProjectFinishedGenerating(EnvDTE.Project project);    
    void ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem);
    void RunFinished();
    void RunStarted(object automationObject, 
        Dictionary<string, string> replacementsDictionary,
        WizardRunKind runKind, 
        object[] customParameters);
    bool ShouldAddProjectItem(string filePath);
}
The first three methods provide access to the IDE extensibility model for the items that have been added and might be opening. The RunFinished and RunStarted methods provide a means for running initialization and clean-up code. RunStarted is a common method to provide an implementation for and to write logic that sets flags used by the ShouldAddProjectItem method; these flags will determine whether an item from the template should be added to the project.
In order to configure the extension, you must modify the VSTemplate element in the template metadata file to add a WizardExtension element that defines the assembly information for your custom wizard extension. The abbreviated template file in Figure 12 shows how this configuration works. When the wizard is run, the wizard extension will be loaded and its methods called at the appropriate time to augment the wizard processing.

Conclusion
Visual Studio 2005 has greatly improved the template capabilities and the ease with which you can create reusable, dynamic templates to provide robust starting points for projects and project items. The use of a simple ZIP file and an XML metadata file make customizing templates straightforward. In addition, the export features in Visual Studio make starting a template as simple as opening an existing project. The samples available for download provide several simple illustrations of the items discussed in this article put to use. See the Visual Studio Template Schema Reference in the MSDN® Library for additional details about adding customization to your template metafiles.

Matt Milner is an independent software consultant specializing in Microsoft technologies including .NET, Web services, XML, and BizTalk Server. As an instructor for Pluralsight, Matt teaches courses on Web services, BizTalk Server and ASP.NET. Matt lives in Minnesota with his wife Kristen and his son Max.

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.
Page view tracker