Ease Versioning Multiple Assemblies by Splitting Up AssemblyInfo

Most .Net project deployments are made up of multiple assemblies and it is common to version all assemblies in a given release with the same version numbers.  Since changing each AssemblyInfo.cs file can be time consuming and error prone, most projects take one of two approaches to solving the problem:

  1. Generate AssemblyInfo.cs files using an nant build scripts and setting properties.
  2. Use a single AssemblyInfo file and have all projects reference that file.

Both approaches have pluses and minuses.  Generating AssemblyInfo.cs can be hard to setup and get correct but is more flexible.  Using a single AssemblyInfo.cs and have each project reference it is easier but all projects will have the same information in the assembly properties.

A hybrid approach that many developers overlook is splitting AssemblyInfo.cs into an assembly specific version and a product wide version.  Each Visual Studio project would contain the standard AssemblyInfo.cs file that is generated by the project templates.  The difference would be that product wide attributes are removed.  See the sample AssemblyInfo.cs file below for an assembly named ClassLibrary1.dll:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ClassLibrary1")]
[assembly: AssemblyDescription("Assembly for ClassLibrary1")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e96237d4-2420-4dc7-aed2-43a121bd0221")]

Notice that several of the standard attributes have been removed.  Those attributes are moved to a file in a central directory so that it can be changed once for several projects.  The following is the contents of a sample file containing these attributes, named ProductAssemblyInfo.cs:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyCompany("My Company")]
[assembly: AssemblyProduct("My Product")]
[assembly: AssemblyCopyright("Copyright ©  2007")]
[assembly: AssemblyTrademark("")]


// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.1.0")]

After creating the product level AssemblyInfo, multiple VS.net projects can reference it and pull in those attributes.  Below is a snapshot of my Solution Explorer within VS.net 2005.  Each project has their own AssemblyInfo.cs but each also has a reference to ProductAssemblyInfo.cs.  Once the solution is rebuilt, each assembly will have the combination of the attributes in ProductAssemblyInfo.cs and the specific AssemblyInfo.cs.


This approach allows each assembly to have a separate AssemblyTitle, AssemblyDescription, GUID, and ComVisible Setting, while maintaining the ability to change the version numbers and company information in one place and have all assembly builds pick up the updated attributes.

If you are using a continuous integration server like CruiseControl.net, a build dependency can be set on the directory containing ProductAssemblyInfo.cs for each individual build in your product deployment.  That way, the entire product will rebuild automatically with new version numbers after ProductAssemblyInfo.cs has been modified.

kick it on DotNetKicks.com


Tags: , , , , ,

Comments

16 Responses to “Ease Versioning Multiple Assemblies by Splitting Up AssemblyInfo”

  1. gugulethun on February 15th, 2008 3:58 am

    Nice article. Very intuitive……. But how if you don’t want your individual assemblies to have the same version?

    …..I hope you have an idea on this one beside putting the Version settings on each of the AssemblyInfo files which is currently not easy to manage.

  2. Darren Stokes on February 15th, 2008 5:18 am

    This approach is for those who want to version all assemblies concurrently. An instance of this might be a product company that wants all assemblies shipped with a version of their product to have the same version number.

    If you want to have different version numbers on your separate assemblies, you should not take this approach. I would recommend you keep the separate assemblyinfo files or generate them in nant scripts.

    An example of generating assemblyinfo files can be found in many open source projects. NHibernate, for instance, takes this approach.

  3. Adam on March 18th, 2008 2:32 am

    “After creating the product level AssemblyInfo, multiple VS.net projects can reference it and pull in those attributes.”

    How do you add a reference to just 1 file? When you add existing, it makes a copy of the file thus severing your single point of entry. Am I missing something?

  4. Darren Stokes on March 18th, 2008 3:12 am

    Adam,

    When you are adding the product level AssemblyInfo file, instead of pressing the add button in the dialog, press the little arrow pointing down that is on the right hand side of the add button. The dialog will give you a menu option to add the file as a link (point to it instead of copy it).

    Hope that helps.

  5. Grant Palin on March 18th, 2008 8:54 pm

    Hey this is pretty neat. I just figured out how to get NAnt to automatically increment the number in my separate projects (3 projects in one solution) so the numbers are the same for each final assembly. But this solution seems like a tidier way to handle that.

    One question though, does this technique work for web projects? One of mine is a web project, and I was not able to “link” the common assembly file to it. Any suggestions?

  6. Darren Stokes on March 19th, 2008 2:23 am

    Grant,

    I just created a solution with a web application project and a class library project and was able to add a link to the common assemblyinfo to both and compile without a problem.

    I’m not sure what the problem could be. Are you getting an error?

  7. Grant Palin on March 19th, 2008 5:39 pm

    My solution has 2 class libraries and one web project. For the libraries, the little arrow on the Add dialog shows 3 options: Open, Open With…, and Link File. For the web project, only the first two options are shown, and not the linking one.

  8. Grant Palin on March 19th, 2008 5:40 pm

    I’m using VS 2002, if it matters. I don’t know if the linking to web projects is possible in VS 2005/8.

  9. Darren Stokes on March 20th, 2008 2:37 am

    That must be the problem. I’m using 2005 and 2008 and it works on both of those. Microsoft must have added this functionality for web projects after 2002.

  10. Grant Palin on March 20th, 2008 5:07 pm

    I figured as much. Nuts for the easy solution…Yet another reason to upgrade!

    I do have VS 2005, from the launch event a few years ago. Have only tinkered with it so far…Guess I should try moving my project over and see what happens!

  11. Conrad Braam on December 19th, 2008 7:11 am

    Great solution. I have a project with about 30 assemblies, and when I noticed the versions and Company/Product name were mostly blank and in some cases filled with well-meaning variations of the correct info (but inconsistent)…
    I just want to know is someone has a top-ten list of commonly broken things on large .NET and WPF projects. It would make it easier to motivate cleaning up the “broken windows” feel if the worst project baddies were ranked and shamed.

  12. Brian on December 30th, 2008 5:15 pm

    I’ve found that this works if all of your projects are of the same language, but what about if you have mixed VB.NET and C#?

  13. Add an existing file to a project without copying it. : Visual Studio Hacks on November 23rd, 2009 2:25 pm

    [...] A few months ago, I posted an article on my blog explaining Versioning Multiple Assemblies by changing one partial AssemblyInfo file. [...]

  14. Neil Johnson on December 8th, 2009 9:18 am

    Great solution – also works for VB – I was wondering if linking worked in VB – and following your instructions – it does!

    Thanks

  15. Gokcer Gokdal on September 1st, 2011 3:07 pm

    Thanks for this elegant solution. It would be helpful if you mention linking the file instead of adding to the project in the text. Also the image is different in VS2010 which shows a small overlay icon ProductAssemblyInfo.cs on file to indicate lin process. Thanks again. It saved serious time in one of my solutions having 17 sub projects.
    With best wishes..

  16. Uma on January 3rd, 2014 5:37 am

    Thanks for the great solution. It would be helpful if we able to override the version number for few assemblies. Is it possible to override it?

Leave a Reply