After a while of creating the same solution structure code over and over again for the some kinds of projects I decided to make a template. Making a single project template was easy: you just follow along the Visual Studio export template wizard but making a solution template with multiple projects was not as simple, hence the reason for this blog post.
I’m using a PC with Windows 8.1 Pro and Visual Studio 2013 with update 4.
Setup Solution
First set up a solution with the projects you want to make into a template. For this example I’ll go with a really simple and stripped down skeleton for a backend solution following the domain driven design. You can fork it here. It’s just a really simple skeleton solution with multiple projects, feel free to go wild and crazy adding stuff and altering it as you like for your template.
This is what my demo project structure looks like
In order to make this into a Visual Studio template we need a .vstemplate file in the root as well as in each project we want to include in the final solution template. The easiest way is to use the template export wizard to export the projects one by one and then add the root template.
Export each project
Go to File ➜ Export Template…
Leave the Project template radio button checked and choose one of the projects in the drop down list
Fill out the template options as you want them and click finish.
The file explorer should pop up with My Exported Templates where your newly exported project is neatly packed into a .zip file. Go ahead and look inside to see to the basic structure and notice that a MyTemplate.vstemplate file is present
Extract the zip file a folder. I’m going to change the name of the Visual Studio Project/Item Template File to DataAccess but you can leave it as is if you want.
I will also change a little thing inside the template metadata by opening the now named DataAccess file with Visual Studio. Here you can see the .vstemplate ending which is what I’ll refer to for the rest of the post.
I’ll change the <Name> tag to DDD Backend Data Access which will make my DataAccess.vstemplate metadata look like this:
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project"> <TemplateData> <Name>DDD Backend Data Access</Name> <Description>Domain Driven Design: Data Access layer</Description> <ProjectType>CSharp</ProjectType> <ProjectSubType> </ProjectSubType> <SortOrder>1000</SortOrder> <CreateNewFolder>true</CreateNewFolder> <DefaultName>DDD_Backend.DataAccess</DefaultName> <ProvideDefaultName>true</ProvideDefaultName> <LocationField>Enabled</LocationField> <EnableLocationBrowseButton>true</EnableLocationBrowseButton> <Icon>__TemplateIcon.ico</Icon> </TemplateData> <TemplateContent> <Project TargetFileName="DDD_Backend.DataAccess.csproj" File="DDD_Backend.DataAccess.csproj" ReplaceParameters="true"> <Folder Name="Properties" TargetFolderName="Properties"> <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem> </Folder> </Project> </TemplateContent> </VSTemplate>
Now repeat this process for each project in the solution. My folder looks like this:
The Solution Template
We are now ready for creating the Root.vstemplate file which will be what binds our project templates together with the solution template. Open up an empty Visual Studio and go File ➜ New ➜ File…
I want all my projects to match my naming convention: “ProjectName.LayerName” and this is done by using a template parameter such as $projectname$. This parameter will be replaced by your input file name in the New Project wizard in Visual Studio.
Paste the following into the xml document:
<VSTemplate Version="3.0.0" Type="ProjectGroup" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"> <TemplateData> <Name>DDD Backend Solution Template</Name> <Description>Domain Driven Design: Backend Solution Template</Description> <ProjectType>CSharp</ProjectType> <ProjectSubType> </ProjectSubType> <SortOrder>1000</SortOrder> <CreateNewFolder>true</CreateNewFolder> <DefaultName>DDD_Backend</DefaultName> <ProvideDefaultName>true</ProvideDefaultName> <LocationField>Enabled</LocationField> <EnableLocationBrowseButton>true</EnableLocationBrowseButton> <Icon>DDD_Solution_icon.png</Icon> </TemplateData> <TemplateContent> <ProjectCollection> <ProjectTemplateLink ProjectName="$projectname$.DataAccess"> DDD_Backend.DataAccess\DataAccess.vstemplate </ProjectTemplateLink> <ProjectTemplateLink ProjectName="$projectname$.Domain"> DDD_Backend.Domain\Domain.vstemplate </ProjectTemplateLink> <ProjectTemplateLink ProjectName="$projectname$.Repository"> DDD_Backend.Repository\Repository.vstemplate </ProjectTemplateLink> <ProjectTemplateLink ProjectName="$projectname$.Services"> DDD_Backend.Services\Services.vstemplate </ProjectTemplateLink> </ProjectCollection> </TemplateContent> </VSTemplate>
Save the file in the root of the folder where you have your project template folders and make sure it ends with .vstemplate which will convert it to a template file. I’ll call mine Root.vstemplate
Alright! We are nearly done. I just want to add a template icon for the solution with the name I specified in the root.vstemplate file <Icon>DDD_Solution_icon.png</Icon>
Now zip the files in this folder by marking them all ➜ Right-click ➜ Send to ➜ Compressed (zipped) folder
Give it a name and add it to your ~\Visual Studio version>\Templates\ProjectTemplates folder
Done! You can now go to New Project in Visual Studio and find the solution template like you would normally do and give it a name.
A tutorial very well done. Very useful .
Thank You!
Great article
I had been wondering if there was more than just exporting a single project template. Thanks for the detailed tutorial!
Hi, yout post is very useful, i have a question, how can I change the project target of my item template?
the question is in :
http://stackoverflow.com/questions/29683407/change-project-folder-path-in-visual-studio-template?noredirect=1#comment47505653_29683407
best regards,
Igor de Andrade Monteiro
Hey, How would this be done and then packaged into a VSIX project? When i create a new Project template and configure the vstemplate file to get the other selected vstemplates; it seems to work. But, once created, it only makes a folder which is empty.
When I follow the directions, Each project is show, not the solution. It works somewhat, but I want it to create the solution with each project as yours does. Did you miss a step in the directions? I am using VS 2012.
Please reply.
Thanks,
Mike
What about dll references? If there’s a dependency between template projects, will it still work?
Hello, is it possible to add “solution items” in the template?
Thank you very much for your great article. If I create a new project with the new template the solution file is not located in the right directory like in your example repository.
Do you know a workaround for this?
Great article, thank you for posting!
However I’m having problems with references not being brought over. I mean, they are listed, the ‘packages’ folder content is there, but the Solution doesn’t know it.
Do I have to include this in any way, inside my Root.vstemplate or any of the included project .vstemplate files?
Thank you so much in advance!
Hi,
I have the same problem, references are there, but broken (with the yellow exclamation mark).
Does this work when you have nuget packages installed on the projects?
For all of the references to other assmeblies (both in code files and in the csproj files) you need to replace the hard coded assembly values with $ext_safeprojectname$.
The ext_ gets the project name from the parent in this case, the solution level, so and example would be
using MyProject.MyOtherAssembly.MyOtherResource;
namespace MyProject.MyAssembly.MyResorce {}
would be:
using $ext_safeprojectname$.MyOtherAssembly.MyOtherResource;
namespace $safeprojectname$.MyResorce {}
Arnie and Renato: The broken references are because when new solution is created, it creates an extra folder level for the projects inside the solution folder. This breaks the original reference to the packages folder which is supossed to be one level above project files and now is 2 levels above.
I still can’t find a fix to avoid this behavior and I was expecting to find it here, but to no avail :(
Elizabeth??
BTW: My only workaround so far (though kind of nasty to my taste) is to edit the project files from each project template to change the paths of the nuget dependencies from “..\packages” to “..\..\packages”. That should point the packages folder in the solution root and make the projects work without issues.
I know! I’t sdisgusting, right?! I haven’t seen as bad a feature as this in Visual Studio ever!
Pingback: itemprop="name">Visual Studio: How to create a solution template with multiple projects - Jonathas Sucupira
Thank you! I’ve been trying to do this for years and haven’t been able to. This method worked very well for me.
Great article, Elizabeth. I have a couple of queries related to it:
1) Why do we need to create multiple projects under one solution? Does it help development of large, complex application?
2) Wouldn’t it be simpler enough to create Folders in one project, in one solution?
I am trying to understand what are the pros and cons of developing large, complex application by:
I) having single project in one solution
II) having multiple projects in one solution
Thanks!
~ Harshit
Pingback: itemprop="name">How To Make A New Solution In Visual Studio | Porazi2
Very very good article
Elizabeth, thank you!
It was really simple and helpful!
Pingback: itemprop="name">How To Add Multiple Project In Visual Studio Solution | Information
Great Article !!! Thanks
Very good. Thanks.
Thanks for article. If my projects are to reference other projects in solution, how do I fix up the references in the individual project files to reflect the given name of each of the projects. I have created a multi-project solution template with the following projects
MyTemplate.Models
MyTemplate.Repositories
…
My MyTemplate.Repositories project has a reference to MyTemplate.Models. When I create a new project from this template and give the project name as MyProject, I get a solution with the following projects
MyProject.Models
MyProject.Repositories
…
The problem Im having is that the reference from MyProjectRepositories to MyProject.Models is broken because it is defined as
which doesnt exist. Using $safeprojectname$ instead of MyProject does not work as it replaces as this
Any help appreciated
I dug around in MSDN for a bit and found this helpful looking document
https://msdn.microsoft.com/en-us/library/8wba5h42(v=vs.100).aspx
It suggests that you can simply use $safeprojectname$ inside of your template files.
Example:
using $safeprojectname$.Infrastructure;
using DDD_Backend.Core.Domain.Identity;
using DDD_Backend.Core.Extensions;
using DDD_Backend.Core.Infrastructure;
using DDD_Backend.Core.Repository.Identity;
using DDD_Backend.Data.Identity;
using DDD_Backend.Data.Infrastructure;
using DDD_Backend.Data.Repository.Identity;
Would be typed as
using $safeprojectname$.Infrastructure;
using DDD_Backend.Core.Domain.Identity;
using DDD_Backend.Core.Extensions;
using DDD_Backend.Core.Infrastructure;
using DDD_Backend.Core.Repository.Identity;
using DDD_Backend.Data.Identity;
using DDD_Backend.Data.Infrastructure;
using DDD_Backend.Data.Repository.Identity;
would be typed as
using $safeprojectname$.Infrastructure;
using $safeprojectname$.Core.Domain.Identity;
using $safeprojectname$.Core.Extensions;
using $safeprojectname$.Core.Infrastructure;
using $safeprojectname$.Core.Repository.Identity;
using $safeprojectname$.Data.Identity;
using $safeprojectname$.Data.Infrastructure;
using $safeprojectname$.Data.Repository.Identity;
Visual Studio does the rest of the databinding during project creation.
Add copyParameters=”true” in Root.vstemplate like below
Use $ext_projectname$ inthe code to resolve project name
using Provider.$ext_projectname$
Muchas gracias :)
Very good post.
Hi,
Thanks for the Great Article. Can i change the projects at runtime ? im creating a template, in which i need to ask user that, what are the projects needs to be included in Solution.
Thanks,
Muthukumar A
For those having trouble dealing with references to other projects, I dug around in MSDN for a bit and found this helpful document: https://msdn.microsoft.com/en-us/library/8wba5h42(v=vs.100).aspx
It suggests that you have to manually use $safeprojectname$ inside of your template files where you refer to the root namespace, and Visual Studio will take care of the data binding.
Example:
using $safeprojectname$.Infrastructure;
using DDD_Backend.Core.Domain.Identity;
using DDD_Backend.Core.Extensions;
using DDD_Backend.Core.Infrastructure;
using DDD_Backend.Core.Repository.Identity;
using DDD_Backend.Data.Identity;
using DDD_Backend.Data.Infrastructure;
using DDD_Backend.Data.Repository.Identity;
Would be typed as
using $safeprojectname$.Infrastructure;
using $safeprojectname$.Core.Domain.Identity;
using $safeprojectname$.Core.Extensions;
using $safeprojectname$.Core.Infrastructure;
using $safeprojectname$.Core.Repository.Identity;
using $safeprojectname$.Data.Identity;
using $safeprojectname$.Data.Infrastructure;
using $safeprojectname$.Data.Repository.Identity;
For anybody having issues with the project references, I wrote up a quick blog post with a working example on GitHub to make sure all those using statements are correctly evaluated.
https://cameronwilby.com/visual-studio-creating-a-solution-template-with-multiple-projects/
Great article!
I used your article to create a template and it worked fine, right now I want to do the same for ASP.NET Core 1.1.0 but I am unable to do it, probably due the new project type (DNX), could you be so gentle to do a new tutorial for ASP.NET Core?
The solution I want to create the template from is this: https://github.com/adenial/TemplateCoreMaterial
Regards
great job
Thanks,
this gave me a great idea to create my own solution via text writing and add projects using a quick forms app for BizTalk projects.
Cheers
I rarely leave comments but it is a great post. Thanks for author.
Hi,
Nice article.
I have the question, how to create solution/project template with .net core library that uses .net core 1.1 frameworks.
Can u please share some sample for it?
Nice article. Thanks for writing it.
I have to make Solution Template, so when I create solution template it includes with multiple projects by using VSIX project, so what changes i need to do to make it work? Please share some sample for it.
Thank you! I’ve been trying to do this for years and haven’t been able to. This method worked very well for me.
How to create only two projects or three projects and not all based on some conditions ?
Can we add conditions in root.vsTemplate? Based on user inputs I would like to use selected vsTemplates and generate selected projects.
Great Post!
Very useful information regarding visual studio it will help me in my project work.
How to add MSBuild props to Solution Template?