Download the code for this article here. (Zip file updated to include source code for VSIX and Wizard projects.)

Earlier this year I authored an open-source toolkit, called Simple MVVM Toolkit, to help developers build Silverlight, WPF and Windows Phone applications based on the Model-View-ViewModel design pattern. To enhance developer productivity, the toolkit combines a set of helper classes with code and xml snippets, as well as Visual Studio item and project templates. After installing the toolkit, all a developer needs to do to get started is open Visual Studio and create a new project by selecting one the project templates that appear under the Mvvm category.

Visual Studio makes it extremely easy to create a single-project template. Simply select Export Template from the File menu and follow the prompts. This will produce a .zip file containing the contents of the project and a .vstemplate text file with xml describing the template content and properties.

There are times, however, when it you would like to create a template which generates multiple projects belonging to a single Visual Studio solution. A good example is the SimpleMvmRiaServices project template shown in the first screenshot, which generates a Visual Studio solution with three projects: an ASP.NET Web project, a Silverlight client project, and a Test project for unit tests. To create this template I first had to create individual templates for each of the three projects, then extract the contents of each zip file in order to combine them into a single multi-project Visual Studio template, with a .vstemplate file describing the contents. Here is an example of a VSTemplate file I created for a Multi-Project WCF REST Template I recently did for a talk I gave at a .NET developer group (some of the content has been elided for clarity).

The template encompasses four project templates: Client, Entities, Service and Web. Notice the variable, $safeprojectname$, which captures what the user entered for the project name in the New Project dialog. There is also a WizardExtension element, which references an IWizard implementation. IWizard allows you to control the template creation process, for example, to allow projects to reference one another or to set project properties, such as the RIA Service project link required for my SimpleMvvmRiaServices template.

For my WCF REST template I wanted the Client and Service projects to both reference the Entities project, and for the Web project to reference the Service project. The problem here is that within each child template, $safeprojectname$ represents the current project name. There needs to be a way to pass in the root $safeprojectname$ from the parent template. This is where the IWizard project comes in.

Start by creating a class library project and referencing the assembly, Microsoft.VisualStudio.TemplateWizardInterface.dll. Create a RootWizard class that implements IWizard. In the RunStarted method you can capture $safeprojectname$ from replacementParameters and store it in a public static Dictionary<string,string> so that it can be captured by a ChildWizard class and stored as $saferootprojectname$ in replacementParameters.

You can now edit project references in child project csproj files, as well as using directives in source code files, to include $saferootprojectname$ where you want the user-entered project name to appear.

Next, make sure to sign your wizard assembly, using a test certificate if you like, and then obtain the public key token by opening a Visual Studio command prompt at the location of your wizard dll and entering the command (replace WizardAssembly with your dll file name):sn –T WizardAssembly.dll

Now that you’ve created a multi-project Visual Studio template, you need a way to deploy it. The best way is to create a VSIX project, which allows you easily publish your template to the Visual Studio Extensions Gallery, so that developers from around the world can install it by selecting Extension Manager from the Tools menu right from within Visual Studio! First you’ll need to install the Visual Studio 2010 SP1 SDK (assuming you’ve first installed SP1 for VS 2010). Then create a new VSIX project (in the Extensibility category that now appears in the New Project dialog). What you get is a nice designer for editing the .vsixmanifest file, where you can set properties and add content.

There are two items you will want to add as content. One is the template wizard assembly you just created, and the other is a zip file containing the multi-project template contents, including both the parent .vstemplate file and icons, as well as a folder for each child project template containing the project contents and .vstemplate file.

The important thing to note here is that the assembly for the IWizard implementation need not be installed into the Global Assembly Cache when it is packaged into the same VSIX project as the templates using it. Another thing you might want to do when adding the template zip file is specify the category under which you want your template to appear in the Visual Studio New Project dialog. In the the case of my WCF REST Template, I have indicated it should appear under the WCF category.

When you build the extensibility project, you’ll get a .vsix file that you can upload to the Visual Studio Extensions Gallery, so that it will appear in the Online Gallery when developers select Extension Manager from the Tools menu. Enjoy.

I created the Multi-project template and installed the VSIX file. I created a new solution using this extension but I am missing dll references. How can I get the dll references fixed? do I always do it manually, please let me know if there is a way to fix this issue. Thanks

Sorry I’ve been so delinquent in responding. I noticed the download file was incomplete, so I updated it to include source code for the VSIX and Wizard projects. The key to getting the project references right is to make sure the relative path is correct and that the root and child wizards are correctly setting the $saferootprojectname$ variable. The project guids also need to match.

There are a number of manual steps to perform and it’s easy to miss something. So I found it useful to install the wizard assembly into the GAC and test the template by copying the zip file to the appropriate location under Documents\Visual Studio 2010\Templates. Keith’s multi-project solution template tool sounds intriguing, and I’ll be sure to check it out.

I’m REALLY not into wheel reinvention, so wanted to take the time to explain why I decided to build something. The premise follows: 1. VS solution files are text files. 2. Working with text files is easy. 3. Creating multi-project solution templates should be easy.

Hi Keith, Appreciate your contrib! Building multi-project solution-based templates can get hairy because of all the different text files you need to hand-edit. Great idea to automate this. Have you published it to the VS Extensions Gallery yet?

When i tried to create this template for Visual Studio 2005, it doesn’t replace the variable $safeprojectname$ and all the projects are create like $safeprojectname$.Web, $safeprojectname$.Persistence and so on. Any suggestion for this?

I am trying to create a multi-project template in VS2012 and have created the required ProjectTemplates & IWizard implementation assembly.
As mentioned by you, we need to add the Wizard assembly as CONTENT in VSIX. But in VS2012 VSIX we don’t have CONTENT tab.
How do I add the IWizard assembly?
Can you help me with this?

If you’re using the VS 2012 SDK, there is an Assets tab. For the Type specify Microsoft.VisualStudio.Assembly. For the Source, you can either select the DLL as a file on the system or, better yet, add the wizard project to the solution and set source to Project in the Current Solution. You can then embed it in the TemplateWizard folder.

I have a multi project template and i want to add a condition in the solution vstemplate file in order to control which project to add, depends on the wizard user input.
the $if$($paramname$==value) does not work in the solution vstemplate file.
any ideas ?

I don’t know if anyone is still coming across this blog but i have created an assembly that can be used directly to expose top level template parameters too all the child templates. It also extends the number of Guids available from 10 to 100. You can find the source or just the binaries if that’s all you need here [GlobalParams|https://globalparams.codeplex.com/]

I don’t know if anyone is still coming across this blog but i have created an assembly that can be used directly to expose top level template parameters too all the child templates. It also extends the number of Guids available from 10 to 100. You can find the source or just the binaries if that’s all you need here https://globalparams.codeplex.com/

I am currently finding that the ProjectName from the ProjectGroup template is replacing the $safeprojectname$ in my using statements. Is this why you use $saferootprojectname$ or is that more specific to your wizard?

I went round in circles a bit, but under VS 2013 you can achieve the $safeprojectrootname$ functionality without a wizard using $ext_safeprojectname$ and the following in the ProjectGroup vsTemplate file.

Now to just resolve my nuget bundling in my VSIX and I can call it a day!

Hi, I created the templates and template wizard in vs2013. I created the vsix file (with the templates and the wizard as assets) and then installed it, All went well. I could also see the template installed under “extension and updates” and under File\new projects. However, when I select the new project and click Ok, Nothing is created. All I see is a status bar at the bottom telling me that the project is created. But the solution explorer is empty and there are no files in windows explorer. I’m not sure what I’m missing. Any guidance would be of great help

It looks like something is wrong with your project template. You should first test the template by placing the zip file you created for it in your local Documents folder – under Visual Studio 2013\Templates\Visual C#. Once you’ve copied the zip file there, you should be able to execute it via the New Project dialog in Visual Studio. After you’ve tested the project template, then you can make it part of your VSIX project.

Thanks a lot. I finally got it. I forgot to add “projectgroup” to my multi project template. It is now working. I have one more question, if you do not mind. I need to add some solution level items. Would you have ay suggestions? I’m already using wizard extension to do NuGet dependencies for my project.

Yes, it’s not well documented how to add solution items from a project template. But I found a way to add a ReadMe file to the solution in a Wizard project by interacting with DTE2. You can find the wizard code here on line 65:_dte2.ItemOperations.AddExistingItem(destReadMePath);
Let me know if this works for you.