Technique Sharing with Project Templates

Visual Studio .NET is a multifaceted gem. You can spend weeks, months, or perhaps a year or more exploring Visual Studio and the .NET Framework. For example, you might be exploring Visual Studio .NET and the Diagnostics namespace for several days before you stumble on BooleanSwitches. (I will get to what a BooleanSwitch is in a few minutes.) However after you have discovered BooleanSwitches, you will likely want to share this information.

A convenient way to cross-pollinate learning with advanced subjects is to create project and item templates. When you select File|New|Project or File|New|File in Visual Studio .NET, the dialog you see that allows you to pick items are defined by templates. For example, the ASP.NET Web Service applet in the New Project dialog makes it easy for you to start building Web Services; this item is defined by a template. What I am suggesting is that when you discover new things about Visual Studio .NET, go ahead and create templates. By creating and sharing these templates you will find it easier for every member of your team to take advantage of every aspect of Visual Studio .NET.

The template I will demonstrate is a BooleanSwitch configuration file. A BooleanSwitch is a class in the System.Diagnostics namespace. The BooleanSwitch supports toggling debugging and tracing code on and off without recompiling your application. The BooleanSwitch works by reading an XML value in the application configuration file. The idea is that if the switch is enabled then your debug and trace code will run; disable the switch and the debug and trace code doesn't run. (You probably have implemented something similar to this. Fortunately, now the .NET Framework supports managing debugging and tracing from an external source file, rather than every programmer implementing a custom version.)

Creating the Basic Project Template Structure

The project and item templates that already exist can be found in the default installation directory C:\Program Files\Microsoft Visual Studio .NET\Vb7\VBWizards. The basic mechanism is that some pre-defined template files exist in this directory. When you select an item in Visual Studio .NET a copy of these files is made and added to your project. For example, when you add a new class to your project (see figure 1) a templated file named file1.vb is uniquely renamed, a default class name is added to the template, and the file containing the class is added to your project. The easiest way for us to duplicate this kind of behavior is to, well, duplicate it.



Click here for larger image

Figure 1: The Add New Item dialog uses a templated source file to add a class to your project.

Every template has the same basic folder structure. Depending on the needs of each template you will find a Scripts, Templates, Images, and HTML folders. Each of these folders contains a sub-folder that indicates the language version of the template. For example, if you have installed the English version of Visual Studio .NET then you will have a 1033 sub-folder in each of these template folders. (Refer to figure 2 for a picture of the folder structure for the BooleanSwitch item template we are creating.)

Figure 2: The BooleanSwitch item template folder structure.

You could create the template from scratch, but it is much easier to find an existing template and copy that. There is an AppConfiguration template that adds an empty App.config file to your project. The state of a BooleanSwitch is defined in an application configuration file, so it makes sense to reuse AppConfiguration template as a starting point for our new template.

To get started copy the AppConfiguration template project from C:\Program Files\Microsoft Visual Studio .NET\Vb7\VBWizards\AppConfiguration (if you installed Visual Studio .NET in the default folder). Paste the AppConfiguration file to the same folder and rename it to BooleanSwitch. The remaining steps will be to modify the template files, create a wizard launching file, a VSDir file, and test the project template. I will explain each of these pieces in the rest of this article.

Modifying Source Files

There are several files that we might have to modify. The specific files depend on the template we are creating. There is a common.js file, a default.js file, and specific files that are related to your template. The files ending with .js are JScript.Net files. These files can be found by searching the Vb7 folder. The .js files contain external code that is employed by the VsWizard.dll. The VsWizard.dll is the part of Visual Studio .NET that copies and modifies template files and adds them to your project.

For our purposes we copied an existing template that is close to the final result. The AppConfiguration template adds an App.config file to your Visual Basic .NET project. We want an App.config file with a BooleanSwitch. Thus we only need modify the source template file named App.config. This file can be found in C:\Program Files\Microsoft Visual Studio .NET\Vb7\VBWizards\BooleanSwitch\Templates\1033\App.config. Listing 1 shows the template file after the switch has been added.

Listing 1: An App.config template file that contains the state information for a BooleanSwitch.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <switches>
      <add name="mySwitch" value="0" />
    </switches>
  </system.diagnostics>
</configuration>

The switch is straight forward. The name of the switch is expressed in the add tag's name attribute and the state is indicated by the value attribute. I defined the switch to be named mySwitch and the value is 0. Any non-zero value is treated is a switch being enabled and 0 indicates a disabled switch. (If we write our code to use a BooleanSwitch then we enable or disable that code by modifying the value attribute of the switch.)

Writing the Wizard Launch File

For Visual Studio .NET to launch the wizard and use the template we have to write a wizard launch file. The wizard launch file is read by Visual Studio, which in turn figures out what wizard application to run. Certainly we could create a custom wizard, but project templates are managed by the VsWizard.dll. This DLL comes with Visual Studio .NET. All we have to do is tell Visual Studio .NET to use it. Listing 2 shows the wizard launch file for the BooleanSwitch template.

Listing 2: The wizard launching file content.

VSWIZARD 6.0
Wizard=VsWizard.VsWizardEngine
Param="WIZARD_NAME = BooleanSwitch"
Param="WIZARD_UI = FALSE"
Param="PROJECT_TYPE = VBPROJ"

I named this launching file BooleanSwitch.vsz. Visual Studio .NET needs a reliable way to find these files. The VSDir file plays this role. After you have defined the wizard launch file place it in the C:\Program Files\Microsoft Visual Studio .NET\Vb7\VBProjectItems\ folder. This also happens to be the folder that contains the VSDir file.

Writing the VSDir File

The VSDir file is read by Visual Studio .NET. These files are used to locate wizard launching files. You need to add a specific entry to the VSDir file located at C:\Program Files\Microsoft Visual Studio .NET\Vb7\VBProjectItems\LocalProjectItems\LocalProjectItems.VSDir. This file contains entries with specific information. I will tell you that I simply copied the AppConfiguration line already in the VSDir file and made the necessary modifications.

You can look in Visual Studio .NET help for information describing what these VSDir entries our. I summarized the meaning of the values in Table 1. Listing 3 contains the entry I added to the LocalProjectItems.VSDir file.

Listing 3: The VSDir file entries are used to find wizard launching files.

..\BooleanSwitch.vsz|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|Boolean
Switch Configuration File|255|#3121|{164B10B9-B200-11D0-8C61-
00A0C91E29D5}|4559| |App.config

 

Entry

Description

..\BooleanSwitch.vsz

Relative path name for the wizard launch file

{164B10B9-B200-11D0-8C61-00A0C91E29D5}

The GUID of a resource file. (You can search the registry if you are curious as to what resource file this is)

Boolean Switch Configuration File

The display name for the template item

255

The sort priority

#3121

A resource identifier for a description

{164B10B9-B200-11D0-8C61-00A0C91E29D5}

A GUID or a DLL path for a DLL that contains an icon for the template

4559

The icon resource identifier

<blank>

Flags (see the Visual Studio .NET help)

App.config

The suggested base file name

Table 1: A summarization of entries in the VSDir file.

When you are finished you will see the Boolean Switch Configuration File applet in the Add New Item dialog. You can open this dialog by selecting File|Add New Item. You can test the BooleanSwitch by declaring an instance of the System.Diagnostics.BooleanSwitch class. Listing 4 contains code that shows you how to test the switch.



Click here for larger image

Figure 2: The Boolean Switch Configuration File applet in the Add New Item dialog.

Listing 4: Testing the Boolean Switch template results.

1:  Public Class Form1
2:      Inherits System.Windows.Forms.Form
3:  
4:  [ Windows Form Designer generated code ]
5:    Private Shared Switch As BooleanSwitch = _
6:      New BooleanSwitch("mySwitch", "For debug text")
7:  
8:   Private Sub DebugWrite(ByVal Text As String)
9:     If (Not Switch.Enabled) Then Exit Sub
10:     System.Console.WriteLine( _
11:       DateTime.Now.ToString() + ":" + Text)
12:   End Sub
13: 
14:   Private Sub Button1_Click(ByVal sender As System.Object, _
15:     ByVal e As System.EventArgs) Handles Button1.Click
16: 
17:     DebugWrite("This is a test!")
18: 
19:   End Sub
20: End Class

Lines 5 and 6 show you how to declare and create an instance of a BooleanSwitch. We identify the external switch to examine as the first parameter of the BooleanSwitch constructor. I encapsulated the switch in a method named DebugWrite. Using this approach I only need test the switch in one location, on line 9. When the switch is enabled information will be written to the console. When the switch is disabled the call in effect becomes an empty function call.

Of course you could use conditional pragmas like #If Debug and accomplish the same thing. However, you would have to recompile your code when you changed the Debug state. Using the BooleanSwitch is an improvement over that.

Summary

BooleanSwitches allow you to toggle whether debug and trace code is run from an external source without recompiling your application. This is a great technique that should be shared with all developers. By making a project item template for the switch we can quickly make it accessible, without for example, all programmers learning to write the switch XML.

Creating a template item requires knowledge of a couple of disciplines, like how to write JScript. In our example, we copied an existing template, modified the templates files to define the new behavior, wrote a wizard launching file, and added an entry to the VSDir file. This approach is always a good start when it comes to creating new templates. For more advanced wizards you may have to create a user interface and customize the JScript code. As always a good way to learn is learn from the efforts of others, and there are dozens of wizards that already exist.

About the Author

Paul Kimmel is a freelance writer for Developer.com and CodeGuru.com. Look for his recent book "Advanced C# Programming" from McGraw-Hill/Osborne on Amazon.com. Paul will be a keynote speaker in "Great Debate: .NET or .NOT?" at the Fall 2002 Comdex in Las Vegas, Nevada. Paul Kimmel is available to help design and build your .NET solutions and can be contacted at pkimmel@softconcepts.com.



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

  • Live Event Date: November 13, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT APIs can be a great source of competitive advantage. The practice of exposing backend services as APIs has become pervasive, however their use varies widely across companies and industries. Some companies leverage APIs to create internal, operational and development efficiencies, while others use them to drive ancillary revenue channels. Many companies successfully support both public and private programs from the same API by varying levels …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds