Tuesday, July 1, 2014

Visual Studio 2013 project templates

.vstemplate is the extension.

While in the process of creating some boilerplate templates for solutions I learned quite a bit. The reason for creating these templates is that we have identified our best practices for using WCF services to wrap dbs and 3rd party APIs in services that we control. Other services related to business logic, workflow and logging have their own solution patterns that are pretty standard. I was searching for a way to automate new services via solution templates. I found that Microsoft surfaces the ability to create custom project templates for Visual Studio that can be used to do just that. There are a few caveats and I can't get everything I need to fully standardize the process without some manual steps or writing custom code, but it's a good start.

There are two basic styles of project templates to choose from - single project and multi project. There is no concept of a solution template. A multi-project template is what I was able to use to create solutions that contain a collection of projects. Here's how it works and some lessons learned that they don't tell you in the limited documentation.

A template collection is designed in a vstemplate file. This file references a vstemplate file for each project you want to include in the solution. The individual project templates point to the items to include in the project (proj file, classes, folders etc). These are single project files.

The documentation says to create a project and export it via VS File menu. This does some work to the proj file and creates the vstemplate. The collection of files is zipped up and put in the My Templates folder of the VS/Projects folder in Documents. If you selected the import option (checked by default) it also puts a copy in the ../Projects/templates folder that makes it available to VS when you create a new project.

The way I created the "solution template" was to create a subfolder in the Visual C# folder of ../templates for that solution type. I moved each proj zip into that. I unzipped the folder contents to their own folder. Then I deleted the zip folders. The multi-project vstemplate is at the solution template root under ../templates/Visual C#. The vstemplate refs each project template.

The good: We can now create projects with all the necessary projects included.

The bad: Haven't found a way to include solution level items in the resultant solution.

The Ugly: We use post-build scripts to set up the service locally in IIS when the configuration is set to Debug. The AppPool name is ProductServiceVx where Product should be only the product name. I thought I could use $safeprojectname$ which should be the user entered value in the new project dialog. This is not so in our situation.

So there are some manual steps for us. Here they are in a nutshell and how we are in the situation.

Create a new project in VS.

Pick a single name that represents the product - for EmployeeDataService, call it EmployeeData. All of the projects will be named using EmployeeData.xxx as the namespace and assembly name! Even the existing classes. In fact you can add $safeprojectnane$ in any files as long as you define replace as true on the element in the vstemplate.

But Wait! I want the proj names to be PeopleData.Interfaces, PeopleData.DTOs etc... They are, but then the classnanes become PeopleData.DTOs and my post build has PeopleData.DTOsVx as the AppPool name. Not what I want. Try as I might, I cannot find documentation on how to affect this declaratively. Hence the manual steps to crack open the projects and make adjustments. This opens up some risk of errors. Its palpable though since it takes so much work to set up a solution with 10 projects including dependencies.

Speaking of dependencies, enable NuGet package restore and bring in external dlls and projects that these depend on. But again, this is minimal compared to the overall time it takes to set up the solutions.

Speaking of time consuming, it did take a while to create the initial solution, then export each project and define the master vstemplate, but I hope it proves to be worthwhile in the end.

No comments:

Post a Comment