Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating a Custom Visual Studio Project Template for Ivonna

0.00/5 (No votes)
10 Oct 2011 1  
Creating a custom Visual Studio project template

Yesterday, I spent the whole day improving the project template for Ivonna, so I thought I might make this world a better place by sharing the details (and some code, too). The main idea is that in order to make the template smarter than just being able to do some search/replace for you, you should go down the path of Visual Studio extensibility (and return alive). Other than that, you have to put your code in an assembly and throw it into the GAC, then reference it in the vstemplate file. Ask Google for the details, they know.

What I'm trying to implement here: whenever a user adds a WebTest project to the solution, the template should do several things:

  1. Determine the project being tested, and add the test project's output to the bin folder of the tested Web. This is what the existing template does.
  2. Determine if the tested Web is an ASP.NET MVC project, and which version, and add the correct System.Web.MVC and Ivonna.Framework.MVC references to the test project. This is what the improved 3.0 template will do.

Finding a Web Project in the Solution

First, you have to list all projects in the solution, and check each one for its Web-ness. Doing the check is easy once you know all the project's GUIDs -- you just compare them to the known Web GUIDs -- one for Web Site, the other for Web Application projects:

static string[] GetWebGuids() {
	return new[] {"{349C5851-65DF-11DA-9384-00065B846F21}", 
                      "{E24C65DC-7377-472B-9ABA-BC803B73C61A}"};
}

Getting the project's GUIDs is a tough challenge. No such property. Fortunately, this link has the code I wouldn't ever be able to figure on my own.

By the way, if you use project.Kind, you won't get it. For example, you'll get a "Windows C# Project" for a C# Web Application project.

Setting the Project's Output Path

Setting the created Visual Studio project's output path from the project template is relatively easy:

private static void SetOutputPath(this Project project, string newPath) {
	var configuration = 
		project.ConfigurationManager.ActiveConfiguration;
	configuration.Properties.Item("OutputPath").let_Value(newPath);
}

Adding the Required References to the Project

The second task can be split into several steps:

  1. Get the project's references.
  2. Find the first, if any, reference to System.Web.MVC.
  3. Get its major version.
  4. Add the same reference to the project being created.
  5. Add the corresponding Ivonna.Framework.MVC reference.

Discovering the List of Visual Studio Project References

A big surprise here: the EnvDTE.Project interface we're dealing with doesn't have a member for the references of the corresponding VS project. We'll have to use the VSLangProj80.VSProject2 interface instead:

public static IEnumerable<Reference> GetProjectReferences
    (this Project project) {
	var vsProject = project.Object as VSProject2;
	return vsProject.References.Cast<Reference>();
}

The reference we're looking for should have its Name property equal to "System.Web.MVC". In order to add this reference to the new project, we cannot use its name, since it's the same for all MVC versions. Fortunately, we can use the full path here:

vsProject.References.Add(mvcReference.Path);

On the other hand, all Ivonna.Framework.MVC.* assemblies have different names; since they're discoverable by Visual Studio, we can use the correct name without the full path:

var version = reference.MajorVersion;
vsProject.References.Add("Ivonna.Framework.MVC." + version.ToString());

That's it. If you need the missing pieces, you'll find the code on GitHub.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here