The Art of Assembly Versions
One of the things I do is writing and maintaining shared components that are used by other developers, for all sorts of projects. One problem that can really hurt is not managing your version numbers vigilantly. For example, say you’ve got two separate projects using CleverTool.dll, version 1.0.0.0 – are you confident that they both reference the same bits? Some truly great bugs happen when they’re different – if one has an important bugfix, and the other has different namespaces, and you’re wondering why this “works on my machine…” Even better if they’re signed and you’re using the GAC to help keep track… Lots of fun.
So this is, in brief, the pattern that I use to communicate changes via version numbers. It’s one way to handle the problem, but of course not the only way. Also, this is for the projects that aren’t [yet] under automated build like CruiseControl; for those I use a different pattern, which will be a separate post..
Building Versions
The .NET assembly version is broken down into {Major}.{Minor}.{Revision}.{Build} (although there is some disagreement about this, and some inconsistent documentation… but lets ignore that for now. You like your definition better? Great, use that one instead.)
Major: Obviously, big sweeping changes to the project: changing .NET framework versions, changing major supporting libraries, or for that matter just rewriting the thing. There is absolutely no expectation of interface compatibility between major versions, and those upgrading should expect breaking changes and have to do some work on their part to take advantage of the new version.
Minor: Slightly less sweeping changes, but still pretty big: major architectural activity, inclusion of big feature sets, etc. There is no expectation of interface compatibility and there will likely be breaking changes. Upgrading minor versions should expect some changes.
There is a lot of room for interpretation between what’s Major and Minor, personally I try to reserve Major for the biggest of changes, and do minor revisions more often. But this is left up to your discretion.
Revision: A change to a project that alters its public interface, but doesn’t necessarily represent adding big features. This could be adding smaller functionality or more commonly, bugfixes and refactoring. Revisions might maintain interface compatibility. Upgrading revisions should be straightforward.
Build: A change that doesn’t alter the public interface, or is otherwise “very small.” We need to re-release the project, and don’t want someone to confuse this release with the previous one. Builds should keep interface compatibility. Upgrading the build shouldn’t require changes to the user’s code. Often CruiseControl.NET gets put in charge of this number, but that’s a topic for another day.
None of this is absolute – there is a ton of space between each of these categories, and this sort of thing is usually left up to the developer’s own discretion. I think it’s important for your organization, or at least for a developer, to have a method to your version naming madness. You like your method better? Great! Post it in the comments for all of us to learn from.


