Blog Posts


DLL Assembly Versioning

Versioning a .NET dll is a particularly challenging task, as there are no less than 3 versions all with different impacts. It's treacherous territory if you are new to versioning, but if you follow some simple rules it gets much easier.

Whenever comes into play you must consider a couple things such as:
When do I change version numbers?
What Systems use these numbers?
Are there any special considerations I should make when coming up with a scheme?

The answer to these questions are rather nuanced and requires knowledge of the types of version numbers, but it is important to keep in mind that version numbers should ALWAYS sort appropriately both at a binary and a text level because many systems sort data differently. For example: and break this rule, when sorted textually is first and binarily, this can wreak havok on systems that do not process data binarily. Make sure you always pad numbers with zeros to four or five digits to fix this. The fail-safe way to version those same binaries would be 0001.0002.0003.0004 and 0001.0012.0003.0004; this obviously makes the version numbers more challenging to read but it will fix a number of issues down the road.

The three types:

This version is used when loading dlls in the net runtime. This is the only version that matters when loading dlls. If you are writing a re-usable library, you should probably never change this version. Changing this could break transitive versioning, and would require you to update runtime <assemblyBindings />. Changing this will almost certainly make your consumers frustrated. Even in the latest version of ASP.NET, Microsoft is not changing this version number.

Suggested Version Number Scheme:
When to increment: Never, Exceptions made for dlls deployed to the GAC

This version is used to determine if an upgrade of a file is needed. ClickOnce applications use this version to determine if the users installed application version is in need of an upgrade. For the most ideal case, this version number should also match the nuspec, or NuGet package version for your redistributable.

Suggested Version Number Scheme:
Semantic versioning

<Year>.<NumberOfMajorReleaseForTheYear: Padded><NumberOfPatchToMajorReleaseForTheYear: Padded>.<BuildServer-BuildNumber: Padded>.<AnyAdditionalMetaData>
`2016.0203.0179.0000` Indicates that this was build number 179 and it was the second major release of 2016 and there were to prior releases of this version.

If you have multiple build servers, without a master server which issues build numbers, there is a possiblitiy of a race condition where version numbers get out of sync. If that is a concern, implement semantic versioning and a service specifically designed to take a project name and return "the next" semantic version.

When to increment: Every single build.

This version should never be used by .net or installers. Applications should use this number to show to users and should be the version that is logged to the log server when errors occur. This number is really up to you it doesn't have to follow any specific format and is most important to human beings trying to report a bug. It could be the word "Maytag", or the name "Bruce Wayne". I like to keep lots of relevant info in here though

Suggested Version Number Scheme (Date parts are as of the time at compilation):
<Year>.<Month: Padded><Day: Padded>.<24-Hour: Padded><Minute: Padded>.<BuildServer-BuildNumber: Padded>-<TargetEnvironment>-<SourceControlId(GitHash)>
Indicates that this was build number 179 and released on march 30th, 2016 at 10:03 pm UTC; the build was meach for production and you can see the exact source at sha `ca987bf0`
When to increment: At lease every deployment to production.

If you use the suggestion here you will be able to look at the informational version, and tie the dll back to source code, verify if it is deployed to the correct environment and when it was compiled.

published on: August 03, 2015

by: Scott Youngblut