Assembly Versioning in SharePoint

Note: Although quite a lot of this post is about using SVN data in versioning, the idea of using the AssemblyFileVersion works with other systems too

Knowing what version of your code is running is important. Last year I was working on a product where the build process actually put the SVN revision number into a constant in a file – which was then compiled into the assembly – and then the product displayed that version on various configuration pages. This was cool, ‘cos it made it very easy to tie the version of a customer’s code that had a problem to a revision in SubVersion. It proved really bloody useful – the number of times that the ‘latest version, which had definitely been installed’ hadn’t been was … surprising. Thus, I promised that I would do similar in my solutions. However, putting the revision number into a file full of constants seemed … untidy.

I began to wonder about simply using the Assembly Version. Well, it turns out that this is quite easy to do, as Tortoise SVN provides a tool for doing this sort of thing. We’ll look at the ‘how’ bit more later, but first, there is a bit of a problem…

Our SharePoint solutions use strong names all over the place – assembly references in page headers, safe control registrations, web parts, features, other assemblies. And the Assembly Version is part of that strong name. Thus, changing the assembly version isn’t something you want to rush out and do every day. SharePoint 2010 does make this easier, in that it has tokens that are replaced with the appropriate strong name during packaging … :

… but I’d only change this if there was some major change. Like I say, it’s a big, key bit of data in the Strong Name. If only there was some sort of Assembly Version that wasn’t part of the strong name – and there is! It’s the AssemblyFileVersion:

Great, but what is this? Well, it’s a second version number, precisely so we don’t have to change all of our strong name references each time we update the version. Microsoft provide a good description of how to use it in KB556041, but a good, short description is:

AssemblyVersion defines the version other assemblies are compiled against in their manifest.  A change in this requires a recompile of dependent assemblies.

AssemblyFileVersion is informational only.  Incrementing the version does not require a recompile of dependent assemblies.  It helps when browsing your bin folder to know which code version you have installed.

If you are making breaking changes to your API, you’ll want to increment AssemblyVersion.  Non-breaking changes like implementation of current methods, or the addition of new types and methods you could increment just the AssemblyFileVersion.  Typically this is done when creating a service pack or deploying bug fixes only.

- Michael Lang

Perfect! We can use that then. Bruce Boughton – whose post I followed - hasn’t posted in a while, so I’m going to copy his steps in case his blog ever vanishes:

  1. Remove the AssemblyFileVersion attribute from the AssemblyInfo.cs file:
    [assembly: AssemblyFileVersion("")]
  2. Create a new VersionInfo.cs.tmpl code file in the Properties folder. (Try adding in the project root, and dragging it into the Properties folder). Put the AssemblyFileVersion attribute in the file. For example:
    [assembly: AssemblyFileVersion("1.0.0.$WCREV$")]

    $WCREV$ will be replaced with the highest Subversion revision number of all files in the project at each build.

  3. Add a pre-build event to the project (all on one line):
    subwcrev "$(ProjectDir)." "$(ProjectDir)\Properties\VersionInfo.cs.tmpl" "$(ProjectDir)\Properties\VersionInfo.cs"

    Make sure that C:\Program Files\TortoiseSVN\bin is on your PATH.

  4. Edit the csproj file. Look for:
    <None Include="Properties\VersionInfo.cs.tmpl"/>
  5. Add the following after it:
    <Compile Include="Properties\VersionInfo.cs"/>

Build the project. The VersionInfo.cs file will have been generated. Add it to the Subversion ignore list, as you do not want it to exist in the repository.

If you want the version number to change with each build, try:

[assembly: AssemblyFileVersion("1.0.$WCREV$.*")]

I would also consider using something like:

[assembly: AssemblyFileVersion("1.0.$WCNOW=%y%m%d$.$WCREV$")]

This will put the year, month and day into the third section of the assembly file version (e.g. 110518 for 2011-05-18) and the SVN revision into the last part.

Okay, cool, but how would we get this value in our code? Say, if we wanted to display it on a page? Well, something like:

public static string SolutionVersion
 Assembly thisAssembly = Assembly.GetExecutingAssembly();
 FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(thisAssembly.Location);
 return fvi.FileVersion;

There is a catch, though – you have to check your code in before building your assembly/solution. Only after the code is checked in can you get the revision number you want to build into the assembly! You might want to check the assembly back in again later, which is fine – but the code has to be checked in first.

Naturally, this isn’t a problem if you’ve got a build server to check code out of source control and do your builds for you.

So there we have inserting useful information into a version field, and how to get that value back so you can use it. It’s also worth noting, you can actually see the AssemblyFileVersion in the properties of the assembly in Windows Explorer.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>