-
Notifications
You must be signed in to change notification settings - Fork 205
Multi project template design
We should have better support for multi-project templates.
The main issue that we have today is the usage of $safeprojectname$
. When there are multiple projects being created the value of $safeprojectname$
changes based on the project being created. This makes it difficult (impossible?) to create templates which create multiple projects.
To solve this we will create a custom wizards which introduces a new template parameter $saferootprojectname$
.
These wizards should be created in a new project in TemplateBuilder, and this assembly should be delivered in the TemplateBuilder NuGet package. Then we can reference this in SideWaffle and others who are creating template packs can use it as well.
Here are some notes from Imar Spaanjaars who prototyped this.
We will need two different wizards RootWizard
and ChildWizard
. RootWizard
is invoked by the main solution template
Added two IWizard implementations: RootWizard and ChildWizard. RootWizard is invoked by the main solution template (more on that later) and ChildWizard is invoked by each child project that opts in on it.
-
RootWizard has a static Dictionary<string, string> to store global stuff.
-
RunStarted in RootWizard stores the current
$safeprojectname$ in a new item called$saferootprojectname$ -
RunStarted in ChildWizard copies the root based parameter into its own collection.
-
In source.extension.vsixmanifest I referenced the custom wizards Assembly so it gets added to the VSIX:
<Assets>
...
<Asset Type="Microsoft.VisualStudio.Assembly" d:Source="Project" d:ProjectName="CustomWizards" Path="|CustomWizards|" AssemblyName="|CustomWizards;AssemblyName|" />
</Assets>
- In CSharp.vstemplate under ProjectTemplates\Web_Sample Multi Project_Definitions I referenced the RootWizard:
<WizardExtension>
<Assembly>CustomWizards, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</Assembly>
<FullClassName>CustomWizards.RootWizard</FullClassName>
</WizardExtension>
- In MyTemplate.vstemplate of the Web and Model project I referenced the ChildWizards:
<WizardExtension>
<Assembly>CustomWizards, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</Assembly>
<FullClassName>CustomWizards.ChildWizard</FullClassName>
</WizardExtension>
This is an opt-in model so you can skip this for separate projects that don't need the root namespace.
- Now you can use the new replacement parameter in code, project, and other files. An example from Default.aspx from the original project
using $saferootprojectname$.Model;
namespace $saferootprojectname$.Web {
and another one from the references in the Web.csproj:
<ItemGroup>
<ProjectReference Include="..\$saferootprojectname$.Model\$saferootprojectname$.Model.csproj">
<Project>{86b92706-ef8d-4894-8a0a-5a13aabd1012}</Project>
<Name>$saferootprojectname$.Model</Name>
</ProjectReference>
</ItemGroup>
It works, but I sure wish this stuff was a little easier. File | Export Solution to Template would be nice ;-)
You can download my work in progress here:
http://imar.spaanjaars.com/Downloads/Other/SideWaffle/side-waffle-master.zip Any questions: fire away.
Imar