AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=309&pId=-1
Speed up with Project Templates
page
by Ameet Phadnis
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 31276/ 83

Introduction

The next version of Visual Studio .NET (whidbey) has some extra added functionality or templates to give you a head start on building internet / intranet applications. Currently, you can only create a web application using the Web Application template under Visual Basic project or C# project. Did you ever wonder that you could have your own template as a startup for any applications you build. Thats where the interesting concept of Project templates come into picture. In this article I will explain what actions are being taken when you create a Visual Basic application for Web. I will also give a small example of building your own template.

So, lets see what exactly Visual Studio does during creating a new application. When you open Visual Studio .NET and create a new application you are presented with the New Project dialog box. The project dialog box has templates for Visual Basic.

Once you type in the project name Visual Studio normally does the following steps-

1. Creates a solution.
2.Adds project to the solution.
3. Adds all the inital files to your project. For example, for Web Application it will add WebForm1.aspx, global.asax, Web.config and Style.css file.

So, it would be interesting to know from where does Microsoft get these files. For this we will have to look at how the folder structure is for Visual Studio .NET 2003. If you have used the default settings when installing Visual Studio .NET 2003 then you can find the folders under Program Files. The folder structure for VB 7 is as follows -

       VB7
              Bin
              DesignerTemplates
              eVBProjectItems
              VB Samples
              VBProjectItems
              VBProjects
              VBUpgrade
              VBWizards

For each Language there are separate folders. For example, Visual Basic has its own folder called VB7, C# - VC# and so on. For this article purpose, we are going to consider Visual Basic.NET only.

The particular folders we need are vbProjects and vbWizards.
Folders required for Project Templates

VBProjects Folder

For the New Project Dialog Box, Visual Studio.NET needs to know from where it needs to pull all the template names for the Visual Basic language. Visual Studio .NET refers to the vsdir file under vbProjects folder. Typical vsdir file has entries like this -

WebApplication.vsz|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|#3008|40|#3009|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|4504| 1|WebApplication1|Web

The above is a typical entry for Web Application. The entry is delimited with | character. The first column defines which vsz file Visual Studio needs to look at to get information on Wizard. The value 4504 in column 7 is the image Visual Studio takes to display in the templates. The 8th column actually represents that this is a Web Application. (I have not seen any documentation by Microsoft which explains this but I did try it and it worked)In case of Web Application, WebApplication1 is the default project name given when you are creating a new Project. For your specific template, you can create your own vsdir file or just create an entry in existing vsdir file.

In short, vdir file is an optional file. Visual Studio.NET new project templates looks at the vsdir file to find out about project templates for the language.

VSZ files actually points to the right template folder under VBWizards folder. vsz file has the information where it needs to go and get the templates for the project. VSZ files represents the item that appears in the add item dialog or project dialog boxes. Typical vsz file looks like -

VSWIZARD 6.0

Wizard=VsWizard.VsWizardEngine.7.1

Param="WIZARD_NAME = WebApplication"

Param="WIZARD_UI = FALSE"

Param="PROJECT_TYPE = VBPROJ"

In short, Visual Studio new project dialog box looks at the vsdir files and the vsdir file looks at vsz files to get information on templates. The vsz and vsdir files are located in the vbProjects folder.

VBWizards

VBWizards folder is where all the information regarding the templates is stored. As in previous section we saw that vsz files direct Visual Studio .NET New project dialog box to the templates folder in VBWizards folder. The project templates folder has two folders namely Scripts and Templates. Both these folders have 1033 folder.

Scripts folder

The scripts folder contains the default.js file. Each project template needs to have this default.js file. The default.js file has the onfinish function which gets executed as soon as the user clicks Finish or Open in the New Project dialog box. I won't explain the complete onfinish function over here. But I would like to highlight some of the major code for this article. Lets look at the following code in default.js -

var strProjectName = wizard.FindSymbol("PROJECT_NAME");

        var strProjectPath = wizard.FindSymbol("PROJECT_PATH");

        var strTemplatePath = wizard.FindSymbol("TEMPLATES_PATH");

The above code gets information on what the project name was entered by the user. The project path is where the user wants to store this project and the template path is from where the project needs to get the default files for this kind of template.

The following code creates the Visual Basic Project in the Solution.

   var project = CreateVSProject(strProjectName, ".vbproj", strProjectPath, strTemplateFile);

The above code will get the user entered project name and use the template project file to create the new project in the solution. Now the question remains on how do we add files to this project. In the same onfinish event we have functions called AddFileToVSProject which allows us to add the template files to our project. For example, to add Webform.aspx page to our project and name it as WebForm1.aspx. The following code is used -

strTemplateFile = strTemplatePath + "\\WebForm.aspx";

item=AddFileToVSProject("WebForm1.aspx", project, project.ProjectItems, strTemplateFile, false);

The above code gets the template file WebForm.aspx for Web Application and while adding it renames it to WebForm1.aspx. If you are creating an Web Application then the WebForm1.aspx page is marked as start up page. The following code helps us in marking a page as start up page.

var configs = new Enumerator(project.ConfigurationManager);

            for(;!configs.atEnd();configs.moveNext())

            {

                configs.item().Properties("StartPage").Value = "WebForm1.aspx";

            }

To summarize, the script folder contains a javascript file called default.js. This default.js file contains onfinish function which is ran when the user clicks on Open on the New Project Dialog box. This onfinish function creates the project and if there are any templates to be added to the project then it adds it for you. It also allows you to rename the objects and set a page as startup page for the project.

Templates folder

Templates folder is where most of your templates will be stored. The templates can be pages, webuser controls, classes or anything you need as startup for any of your projects. In case of Web Application, the following files are in the templates folder -

1. WebForm.aspx - which gets renamed to WebForm1.aspx.
2. Global.asax - This is copied as it is without renaming it.
3. Web.Config - This is copied as it is without renaming the file.
4. Style.css - This is copied as it is without renaming the file.
5. WebApplication.vbproj - This file is used as template but renamed it to the user entered project name.
6. AssemblyInfo.vb - This file is copied as it is.

In this section, I explained how the folders play a role in your project templates. The next section explains some of the keywords that might come in use while building your own Web Project Template.

Variables that might come in use...

Variables used by Visual Studio environment -

This section will give you some idea on how some of the Variables are used by Visual Studio .NET while creating your project. Lets consider Web Application project template. When a project is created you get a WebForm1.aspx page. If you look at the properties page, and check the codebehind property and the inherits property, you will notice that Visual Studio has already assigned the property WebForm1.aspx.vb to Codebehind and <rootnamespace>.WebForm1 for Inherits. So, how does Visual Studio determine what property value needs to be assigned. Here are some keywords/variables I found when researching the templates. I have not seen any document pointing me to all Variables yet.

1. $FILENAME$ - This is used for the Codebehind property. If you open WebForm.aspx in notepad under templates folder for WebApplication, you will see the following code -

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="$FILENAME$.vb" Inherits="$INHERITS$"%>

When adding the WebForm.aspx to the project, Visual Studio.NET replaces the $FILENAME$ to the respective filename given. In Web Application case, the Webform.aspx is being added as WebForm1.aspx. So, codebehind will change to WebForm1.aspx.vb.

2. $INHERITS$: Referring back to the above code. You can see Visual Studio is using the $INHERITS$ keyword over here. So, when Visual Studio.NET creates the file it will get the rootnamespace and concate it with the filename without the extension. The reason it gets the filename without the extension because by default Visual Studio has the same filename as the classname. So, if you are creating project XYZ as Web application by default you will have XYZ.Webform1 as value for INHERITS property.

3. $CLASSNAME$: This is the one I found useful in one of my application template. Let us consider you are building private assembly or module for a bigger application. You want the class to be included in the same namespace as the application. Say the application name is XYZApp. So, instead of using the $INHERITS$ in your page template for property INHERITS, you can use something like this -

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="$FILENAME$.vb" Inherits="XYZAPP.$CLASSNAME$"%>

So, in case you are building Private Assembly and has a form called XYZPA then the inherits will have the value XYZAPP.XYZPA.

4. SAFE_ITEM_NAME: Lets assume that you are building private assembly and it has a class file with the same name as application. So, if you are creating application XYZ then you would like to have class called XYZDB. So, you can create a template file for your class called may be templatedb.vb. As explained in previous section, the onfinish function in default.js can copy the file and rename it. You can add the following code in your default.js file -

strTemplateFile = strTemplatePath + "\\templateDB.vb";

newfilename = strProjectName + "DB.vb";

item = AddFileToVSProject(newfilename, project, project.ProjectItems, strTemplateFile, false);

The above code will get the project name and combine it with string db.vb and create a new file,  in our case XYZDB.vb. Visual studio.NET will use the XYZDB to replace the following code in your XYZDB.VB file -

Public Class [!output SAFE_ITEM_NAME]

to

Public Class XYZDB

5. PROJECT_NAME: This basically has the project Name assigned by the user. When we create Web Application project with the name XYZ this variable is populated.

6. PROJECT_PATH: This stores where the project is being created.

7. TEMPLATES_PATH: Stores the template folder information for the project type.

These are some of the variables Visual Studio .NET uses while creating your project.

Putting all together

Putting it together –

In this section we are going to build a sample template using the knowledge in this article. Let us assume that we have an application called XYZApp. Developers build their own modules that actually plugs into  the bigger application XYZApp. All modules will have at least one web user control and one Class file. The Web User control file name by default should have the same name as project name. The class file should have the same name as project with the word DB at the end. For example, you are creating XYZMod module then the user control should be called XYZMod.ascx and the class file should be called XYZModDB.vb. The class in the XYZModDB should be called XYZModDB. All the classes should fall under the XYZApp namespace.

 

To achieve this first you need to create the tempXYZ.ascx and tempDB.vb files. You will also need Assemblyinfo.vb file.

The best way to do this is –

  1. Create new Web Application called tempXYZMod.
  2. Once Visual Studio.NET creates the Web application, delete all the files except for the AssemblyInfo.vb file.
  3. Add Web User Control called tempXYZ.ascx.
  4. Add class called tempDB
  5. Save the application.
  6. Open the code for tempXYZ.ascx
  7. At the top before Public Class tempXYZ insert the namespace XYZApp. So, now your code will look like     

                        Namespace XYZApp

                                    Class tempXYZ

  1. Open the tempDB class code. Insert the namespace as above.
  2. Save the application

 

Now you can close Visual Studio.NET. Follow these steps to create your template folder –

  1. Under Program Files -> Microsoft Visual Studio .NET 2003->vb7->vbWizards. Create a folder called XYZMod.
  2. Under this folder create two folders Scripts and Templates.
  3. Under Scripts folder create another folder called 1033
  4. Copy the default.js file from Webapplication->Scripts->1033 folder.
  5. Under Templates folder create folder called 1033.
  6. Copy tempXYZ.ascx, tempXYZ.ascx.vb, tempDB.vb, AssemblyInfo.vb and tempXYZMod.vbProj files from your application folder to the templates->1033 folder.
  7. Open tempXYZ.ascx in notepad.
  8. Change the CodeBehind property value from "tempXYZ.ascx.vb" to "$FILENAME$.vb"
  9. Change the Inherits property value from " tempXYZMod.XYZApp. .tempXYZ " to "XYZApp.$CLASSNAME$".
  10. Save this file and close it.
  11. Open tempXYZ.ascx.vb file in notepad.
  12. Change the class name from Public Class tempXYZ to Public Class [!output PROJECT_NAME].
  13. Save and close this file.
  14. Open the tempDB.vb file in notepad.
  15. Change the class declaration from Public Class tempDB to Public Class [!output SAFE_ITEM_NAME].
  16. Save and Close this file.
  17. Open the tempXYZMod.vbProj file.
  18. Remove everything under <Files><Include> tag. It should just have <Files><Include></Include></Files>.
  19. Save and Close this file.
  20. Go to the Scripts->1033 folder and open default.js file in notepad.
  21. Comment out all the code in Javascript file that adds - Global.ascx, Web.Config, Style.css and Webform.aspx files to the project.
  22. Also comment out the code that sets the WebForm1.aspx as start up page.
  23. Change the code that points to the Webapplication.vbproj to point to tempXYZMod.vbproj.
  24. Add the code to add the tempXYZ.ascx, tempXYZ.ascx.vb and tempDB.vb files to the project and rename the files to <projectname>xyz.ascx, <projectname>.ascx.vb and <projectname>DB.vb.
  25. Now your Javascript file will look as follows –

//

// Copyright (c) Microsoft Corporation 2001-2002. All rights reserved.

//

 

function OnFinish(selProj, selObj)

{

    var oldSuppressUIValue = true;

    try

    {

        oldSuppressUIValue = dte.SuppressUI;

        var bSilent = wizard.FindSymbol("SILENT_WIZARD");

        dte.SuppressUI = bSilent;

 

        var strProjectName = wizard.FindSymbol("PROJECT_NAME");

        var strProjectPath = wizard.FindSymbol("PROJECT_PATH");

        var strTemplatePath = wizard.FindSymbol("TEMPLATES_PATH");

        //var strTemplateFile = strTemplatePath + "\\WebApplication.vbproj";

        var strTemplateFile = strTemplatePath + "\\tempXYZMod.vbproj";

        var project = CreateVSProject(strProjectName, ".vbproj", strProjectPath, strTemplateFile);

        if( project )

        {

            strProjectName = project.Name;  //In case it got changed

 

            var item;

            var editor;

 

            //strTemplateFile = strTemplatePath + "\\Global.asax";

            //item = AddFileToVSProject("Global.asax", project, project.ProjectItems, strTemplateFile, false);

 

 

                    //item = DoesFileExistInProj(project,"Web.config")

            //if (item == null)

            //{

              // strTemplateFile = strTemplatePath + "\\Web.config";

               //item = AddFileToVSProject("Web.config", project, project.ProjectItems, strTemplateFile, false);

            //}

 

            //strTemplateFile = strTemplatePath + "\\Styles.css";

            //item = AddFileToVSProject("Styles.css", project, project.ProjectItems, strTemplateFile, false);

 

 

            var strRawGuid = wizard.CreateGuid();

            wizard.AddSymbol("GUID_ASSEMBLY", wizard.FormatGuid(strRawGuid, 0));

 

            strTemplateFile = strTemplatePath + "\\AssemblyInfo.vb";

            item = AddFileToVSProject("AssemblyInfo.vb", project, project.ProjectItems, strTemplateFile, false);

            if( item )

            {

                item.Properties("SubType").Value = "Code";

            }

           var newfilename;

            strTemplateFile = strTemplatePath + "\\tempXYZ.ascx";

            newfilename = strProjectName + ".ascx";

            item = AddFileToVSProject(newfilename, project, project.ProjectItems, strTemplateFile, false);

 

            strTemplateFile = strTemplatePath + "\\tempXYZ.ascx.vb";

            newfilename = strProjectName + ".ascx.vb";

            item = AddFileToVSProject(newfilename, project, project.ProjectItems, strTemplateFile, false);

 

            strTemplateFile = strTemplatePath + "\\tempDB.vb";

            newfilename = strProjectName + "DB.vb";

            item = AddFileToVSProject(newfilename, project, project.ProjectItems, strTemplateFile, false);

 

 

//            AddDefaultWebFormsPropertiesToWizard(dte, wizard, project);

//            strTemplateFile = strTemplatePath + "\\WebForm.aspx";

 //           item = AddFileToVSProject("WebForm1.aspx", project, project.ProjectItems, strTemplateFile, false);

 

//            var configs = new Enumerator(project.ConfigurationManager);

 //           for(;!configs.atEnd();configs.moveNext())

 //           {

  //              configs.item().Properties("StartPage").Value = "WebForm1.aspx";

  //          }

  //          editor = item.Open(vsViewKindPrimary);

  //          editor.Visible = true;

 

            project.Save();

        }

       

        return 0;

    }

    catch(e)

    {  

        switch(e.number)

        {

        case -2147024816 /* FILE_ALREADY_EXISTS */ :

            return -2147213313;

 

        default:

            SetErrorInfo(e);

            return e.number;

        }

    }

    finally

    {

        dte.SuppressUI = oldSuppressUIValue;

    }

}

 

 

  1. Go to VB7->vbProjects folder.
  2. Make a copy of WebApplication.vsz file and name it XYZMod.vsz.
  3. Open the XYZMod.vsz file.
  4. Change the Param="WIZARD_NAME = WebApplication" to Param="WIZARD_NAME = XYZMod"
  5. Your file should look like –

VSWIZARD 6.0

Wizard=VsWizard.VsWizardEngine.7.1

Param="WIZARD_NAME = XYZMod"

Param="WIZARD_UI = FALSE"

Param="PROJECT_TYPE = VBPROJ"

 

  1. Save and Close this file.
  2. Open Notepad and enter the following entry –

XYZMod.vsz|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|XYZ Module Template|1|XYZ Module Assembly Template|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|4503| 1|XYZMod

  1. Save this file as XYZMod.vsdir
  2. Close this file.
  3. Now Close Visual Studio .NET 2003 if it is open
  4. Open Visual studio.NET 2003.
  5. Go to File New Project.
  6. Under Visual Basic Projects you should see new entry under templates list called XYZ Module template.
  7. Under location type in http://localhost/testXYZMod (make sure it is pointing to webserver because this is web application).
  8. Click open.
  9. You may be asked whether you want to overwrite the ascx.vb file. Just click Yes.
  10. Now you have your startup application ready. You can open the testXYZMod.ascx file and make sure codebehind and Inherits property are pointing to the right values. Inherits will be pointing to XYZApp.testXYZMod and your Codebehind should be pointing to testXYZMod.ascx.vb.
  11. Now open the testXYZMod.ascx file and check whether you the class name has testXYZMod.
  12. Similarly check the changes in the class file too.

 

The above procedure allowed you to create a module template for your bigger application. The templates can save lot of time in coding. Many developers spend too much time adding the same code over and over again. You can also build Visual Studio.NET add-ins to automate some of your coding. I used the above template building wizard for the famous DotNetNuke Private assembly with some Visual Studio.NET add-in to automate new Module development. The whole process for simple modules used to take 2 hours and now it is down to 30 minutes.

 

Summary – In this article, I have explained how project templates can be used to save time for your code. You can have variations in your templates like having imports statement in your codebehind file or use references in your project file. This will standardize the process for all your developers building modules or applications.


Product Spotlight
Product Spotlight 

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-20 8:33:54 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search