I'm in the process of creating a set of Visual Studio templates to share with the community - pretty simple stuff, but can be quite a time saver. In the past I've posted about how to streamline coding using templates, and while the process for packaging templates outlined in that post works, it's pretty manual, and that's not going to work if I'm going to maintain and grow these things. Enter MSBuild. But before I go into that, lets review how I've organized the solution.
The solution is called "ArcDevelper.Templates" - and it simply contains a bunch of other projects that contain the template files, as shown in the following graphic.
Each project simply has the template file (class.cs for example), an associated icon, and the vstemplate file that tells Visual Studio how to transform the file. It's important to note that I'm are just using Visual Studio as an editing environment, and the solution as an organizational scheme - we do not actually "build" anything in the traditional sense.
First off the projects would not compile because the still have string parameters in them that get replaced when the templates are run (see my previous post on templates for more). What we want to do is package the files so they can be used as "templates" - this is where MSBuild comes in.
The MSBuild Script
The other thing I have in the solution is a build.xml file that actually extracts out the files, puts them into zip files and moves them to my "ItemTemplates" folder. With this in place, I can easily make changes to my templates, re-run the build script, and have the updated templates immediately available.
In order to make this work, I had to use MSBuild "batching", which is not exactly intuitive. Without getting into too much about MSBuild (Google it - there's ton's of info around), when creating the itemgroup that will be fed into the target (the actual zip & copy), you need to create some metadata for the items, and then use the Outputs attribute of the Target to subset the items by some of the metadata. As an old client of mine used to say - clear as mud. Maybe this will help...
<ItemGroup>
<Projects Include="$(SolutionDir)\csclass">
<path>$(SolutionDir)\csclass</path>
<zipname>CSClass</zipname>
<itemname>Class</itemname>
</Projects>
<Projects Include="$(SolutionDir)\vbclass">
<path>$(SolutionDir)\vbclass</path>
<zipname>VBClass</zipname>
</ItemGroup>
This is the Item Group that lists the templates (projects) that we will be working with. The path, zipname and itemname sub-elements are the metadata I was talking about. This is then used by the target...
<Target Name="Build" Inputs="@(Projects)" Outputs="%(Projects.ZipName)">
<!-- Create a list of the files in the output folder-->
<CreateItem Include="%(Projects.path)\%(Projects.itemname).*">
<Output TaskParameter="Include" ItemName="FilesToZip" />
</CreateItem>
<!-- Zip the files-->
<Zip Files="@(FilesToZip)" ZipFileName="$(BuildFolder)\%(Projects.zipname).zip" Flatten="true"/>
</Target>
The target specifically notes the inputs and the outputs. Apparently by specifying a metadata item in the outputs forces MSBuild to group / subset the items (depending on how you want to think about it) by that item. In my case, the item is unique - so I get the effect of simply looping over the list.
Anyhow - now I've got this all working smoothly, so I'll add some more stuff into the templates, and then load it up into the ArcDeveloper.net Subversion repository over at SourceForge. I'll post about the actual templates when they are up there.
I'm Dave and this is my blog. I'm usually writing about .NET Software Development, ArcGIS, or Agile Practices, but other stuff does creep in from time to time. I hope you find something of use, and feel free to contact me if you have any questions. You can also check out my profile on LinkedIn
dojo.DTSAgile.com is our technology preview / demo site. As I and my team cook up cool things we post them here.
ArcDeveloper.net is a site that hosts a set of open source projects related to ArcGIS. This includes Tile Cache for .NET (TC4N) and Feature Server for .NET (FS4N). Come over and check it out!
Assembla is a free service that provides Subversion source control, wikis and work Tracking. The ArcDeveloper project is run from here. It rocks. Check them out today.
Agilistas is a LinkedIn group focused on discussing and promoting Agile practices. Everyone is welcome to join in the conversation as we evolve the process of creating software to make it more enjoyable for all involved.