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:
- Generate AssemblyInfo.cs files using an nant build scripts and setting properties.
- 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("184.108.40.206")] [assembly: AssemblyFileVersion("220.127.116.11")]
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.