As of this morning, I posted a new version of my Xamarin.Forms with Caliburn.Micro Starter Kit on the Visual Studio Marketplace.
This video provides a quick walk-through of using the template.
As of this morning, I posted a new version of my Xamarin.Forms with Caliburn.Micro Starter Kit on the Visual Studio Marketplace.
This video provides a quick walk-through of using the template.
Hey all! I’ve bundled my walkthrough of setting up a Xamarin.Forms to use Caliburn.Micro for Android, iOS and UWP into a Visual Studio Project Template and made it available in the Visual Studio Extensions Gallery.
You can download it directly here, or from within Visual Studio: Tools –> Extensions and Updates –> Online.
Update 10/18/2017:
As a multi-project, it’s very straight forward to use, simply choose File –> New and select “Xamarin.Forms with Caliburn.Micro”
Will create a project with the following structure:
Which, when run (on your platform of choosing) looks like this screenshot below. This is right where we left off from my walk-through earlier this year and is a great starting point for prototyping or building your next app.
The source code for the starter kit can be found here. Let me know what you think!
Earlier this year I provided a walkthrough of setting up a Xamarin.Forms project that leveraged Caliburn.Micro for Android, iOS and UWP. I had big plans for extracting the contents of that walkthrough and providing it as a NuGet package. Plans changed however, and I’ve decided to package the entire solution as a Multi-Project Template and provide it as an add-on to Visual Studio (VSIX). This post introduces provides a walk-through on how to create multi-project templates.
First off, as an aside, let’s go back and look what I wanted to do. I wanted to provide a starter-kit of files that would jump start your efforts and allow you to modify my provided files as you see fit. As a NuGet package, I can deliver these files to any project simply by adding these loose code files in the content folder of the NuGet package. Two things that are really awesome about this: the code files can be treated as source code transforms by changing their extension to *.pp, and through platform targeting I could deliver different content files per platform (Xamarin.iOS10, Xamarin.Android10, uap10.0, etc). With this approach, you would simply create a new Xamarin.Forms project then add the NuGet package to all projects. Bam. Easy.
But there are a few problems with this approach:
Above all else, the NuGet documentation clearly states that these files should be treated immutable and not intended to be modified by the consuming project. And since the best place to add the package is immediately after you create the project using a Visual Studio Template, why not just make a Template?
While Multi-Project Templates have been around for a while, their tooling has improved considerably over the last few releases of Visual Studio. Although there isn’t a feature to export an entire solution as a multi-project, they conceptually work the same way as creating a single project template and then tweaking it slightly.
There are two ways to create a Project Template. The first and easiest is simply to select Project –> Export Template. The wizard that appears will prompt you for a Project and places your template in the My Exported Templates folder.
The second approach requires you to install the Visual Studio SDK, which can be found as an option in the initial installer. When you have the SDK installed, you can create a Project Template as an item in your solution. This project includes the necessary vstemplate files and produces the packaged template every time you build.
Effectively, a Project Template is just a zip file with a .vstemplate file in it. A Multi-Project Template has a single .vstemplate that points to templates in subfolders. Here’s how I created mine:
Using the Visual Studio SDK, I created a Project Template project to my solution and modified the VSTemplate file with the appropriate details:
<VSTemplate Version="2.0.0" Type="ProjectGroup" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"> <TemplateData> <Name>Xamarin.Forms with Caliburn.Micro</Name> <Description>Xamarin.Forms project with PCL library.</Description> <ProjectType>CSharp</ProjectType> <Icon>_icon.ico</Icon> <DefaultName>App</DefaultName> <ProvideDefaultName>true</ProvideDefaultName> <CreateNewFolder>true</CreateNewFolder> <RequiredFrameworkVersion>2.0</RequiredFrameworkVersion> <SortOrder>1000</SortOrder> <TemplateID>Your ID HERE</TemplateID> </TemplateData> <TemplateContent/> </VSTemplate>
Next, simply export all the projects in your solution that you want to include in your template. The Project –> Export Template dialog looks like this:
Once you’ve exported the projects as templates take each of the zip files and extract them into a subfolder of your Template Project. Then, in Visual Studio, include these extracted subfolders as part of the project. Note that Visual Studio will assign a default Action for each file, so code files will be set to Compile, images will be set as EmbeddedResource, etc. You’ll have to go through each of these files and change the default action to Content, copy if newer. It’s a pain, and I found it easier to unload the project and manually edit the csproj file directly.
Now that we have the embedded projects included in the output, we need to modify the template to point to these embedded templates. Visual Studio has a set of reserved keywords that can be used in the vstemplate and code transforms; $safeprojectname$ is a reserved keyword that represents the name of the current project. My vstemplate names the referenced templates after the name that was provided by the user:
<VSTemplate Version="2.0.0" Type="ProjectGroup" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"> <TemplateData> ... </TemplateData> <TemplateContent> <ProjectCollection> <ProjectTemplateLink ProjectName="$safeprojectname$" CopyParameters="true">XF\MyTemplate.vstemplate</ProjectTemplateLink> <ProjectTemplateLink ProjectName="$safeprojectname$.Android" CopyParameters="true">XF.Android\MyTemplate.vstemplate</ProjectTemplateLink> <ProjectTemplateLink ProjectName="$safeprojectname$.UWP" CopyParameters="true">XF.UWP\MyTemplate.vstemplate</ProjectTemplateLink> <ProjectTemplateLink ProjectName="$safeprojectname$.iOS" CopyParameters="true">XF.iOS\MyTemplate.vstemplate</ProjectTemplateLink> </ProjectCollection> </TemplateContent> </VSTemplate>
If the ProjectName is omitted, it will use the name within the embedded template.
To ensure the project compiles, we must fix the project references to the PCL library in the iOS, Android and UWP projects. Here we leverage an interesting feature of Multi-Project templates – Visual Studio provides special reserved keywords for accessing properties of the root template project. In this case, we can reference the safeprojectname of the root project using the $ext_safeprojectname$ reserved keyword. And because project references use a GUID to refer to the referenced project, we can provide the PCL project with a GUID that will be known to all the child projects – in this case, we can use $ext_guid1$.
The <ProjectGuid> element in the PCL Project must be configured to use the shared GUID:
<PropertyGroup> <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProjectGuid>{$ext_guid1$}</ProjectGuid> <OutputType>Library</OutputType> <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>$safeprojectname$</RootNamespace> <AssemblyName>$safeprojectname$</AssemblyName> <FileAlignment>512</FileAlignment> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkProfile>Profile259</TargetFrameworkProfile> <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <NuGetPackageImportStamp> </NuGetPackageImportStamp> </PropertyGroup>
In the projects that reference the PCL, the path to the project, project GUID and Name must be also be modified:
<ItemGroup> <ProjectReference Include="..\$ext_safeprojectname$\$ext_safeprojectname$.csproj"> <Project>{$ext_guid1$}</Project> <Name>$ext_projectname$</Name> </ProjectReference> </ItemGroup>
Lastly, there will be some other fix-ups you will need to apply. These are things like original project names that appear in manifest files, etc. The templating engine can make changes to any type of file, but you may need to verify that these files have the ReplaceParameters attribute set to True in the .vstemplate file.
With this in place, you can simply compile the Project Template and copy the zip to ProjectTemplates folder. Optionally, you can add a VSIX project to the solution that you can use to bundle our Project Template as an installer that you can distribute to users via the Visual Studio Extensions Gallery.
Happy coding!