Visual Studio .NET supports a number of built in project types and wizards that generate skeleton projects and solutions depending on the type of application the developer intend to build. These project templates are an excellent way to automate the basic plumbing required for very common project types, such as Windows Applications, Class Libraries and Web Services. However, Visual Studio .NET supports only those basic project types that are extremely common across the developer community. Given the wide diversity and disparity of developer needs, Visual Studio .NET (and for that matter, previous versions of Visual Studio as well) expose an extensible architecture, where developers can write their own custom project types and wizards. This is an excellent feature that allows developers to write canned skeleton code that can be generated automatically, without having to resort to the infamous "copy-paste" anti-pattern. One of the strongest motivations for writing custom wizards is to write skeleton code once, and have it automatically customized, generated, and added to further projects. In this article, we will explore Visual Studio .NET's support for building custom wizards, and discuss how developers can create their own wizards and project templates. Further, we will build a sample wizard that generates a class that maintains a thread pool holding a specified number of threads. Each of these threads will call a user specified method via the use of
delegates. All the thread management will be handled by the generated code.
Note: this article is based on Visual Studio .NET Beta 2 and Windows 2000.
In this article, we use the words
Wizards and
Templates interchangeably.
Existing Projects Types and WizardsThe following screen shot shows some of the project templates and wizards that are supported by Visual Studio .NET by default.
When a project type and template is chosen, Visual Studio .NET creates a solution and project based on the user's selection, and generates some files that contain the skeleton code. Some project templates, like the
Class Library template, generate very simple code that contains one class and a stub for its constructor, while templates such as
Visual Studio .NET Add-ins or
ATL Server generate quite a few files, each containing substantial code. This generated code is usually stored in a file with placeholders for user input values, such as the class and project name. When a specific project type is chosen, Visual Studio .NET invokes a component that reads these canned (also known as templated) files, and substitutes the placeholders with the user input values. Next, this component creates the required projects and solutions using the
Visual Studio .NET Extensibility model. Visual Studio .NET looks for specific files in a fixed location that contain information about the available project templates, and the components that will be responsible for creating new projects based on that template. We will cover this architecture in the next section.
Visual Studio .NET Project Template ArchitectureVisual Studio .NET uses a component based model to support the project templates. Each project template has a corresponding component that handles requests for the given template. A single component can handle requests for multiple templates as well. Visual Studio .NET uses two types of files that are used to identify the project templates, and the components that handle requests for these project templates. The first file (identified by a .vsz extension) contains information about the component, and any custom parameters that the component handling the project template might need. The second file (identified by a .vsdir extension) contains information about the description of the project type, and display properties in the
New Project dialog box. Let us now explain these two files in deta