views:

308

answers:

3

Hello,

there is a way of incrementing the version number of an assembly automatically if the assembly has changed after doing a build of the solution?

I've tried with post-build events but then you increment the version on each build, not only if the build process has compiled anything due to changes.

Thanks in advance.

EDIT: What I want to do is to automatically increment the version number of the assemblies where I change code each time that I do a "Build Solution" to avoid changing it by hand. This way I can be sure that 2 assemblies with the same version ALWAYS have the same code.

A: 

If my understanding of the process is correct, when you do a build of your solution, only the assemblies that have changed (or those where linked assemblies have changed) are rebuilt.

If an assembly didn't change at all, it won't be recompiled (unless you use "rebuild all" command)

So in my projects, inside AssemblyInfo.cs of each project, I have this line:

[assembly: AssemblyVersion("1.0.*")]

And this prodcuces me different version numbers for my assemblies.

Shimrod
+3  A: 

Yes, you can get automatic version incrementing by using * in the [AssemblyVersion] attribute. Unfortunately, that is rarely correct. What Microsoft should have done is give the [AssemblyFileVersion] that capability. They didn't.

[AssemblyVersion] is a very important attribute, used by the CLR to verify that the assembly that got loaded is compatible with the assembly that was used when the code was compiled. "Compatible" means: the assembly is going to work cleanly with the client code, no changes were made to the assembly source code that could make it fail to work correctly if the client wasn't recompiled. Using that definition, a bug fix update is very compatible. An update that reorganized the internal implementation of the classes in the assembly could be very compatible as well. Changes to publicly visible classes or members is likely to not be compatible. Although the JIT compiler is very good at detecting when the changes were grossly incompatible (like removing a previously public member).

Using * in the attribute essentially means: it is always incompatible. Even if you didn't change any code at all, the assembly will be incompatible after it is built again. That's pretty useless in most any scenario, except if you always build the assembly together with its client code. And redeploy them together. That works, but then the notion of having a version number at all becomes fairly useless.

Long story short: IMO you should manage the assembly version yourself. Change it when you make a breaking change in the public interface of the assembly. That's certainly the approach that Microsoft takes. .NET 2.0 assemblies are still marked as version 2.0.0.0 in the .NET 3.5 SP1 framework. Even though they are not actually compatible anymore, WaitHandle.WaitOne(int) got added later. They did otherwise a stellar job of maintaining compatibility for the past 5 years, it couldn't have been easy.

Note that none of this applies to [AssemblyFileVersion], auto incrementing it for every build is very appropriate.

Hans Passant
Does changing build and revision numbers and leaving major and minor numbers intact render an assembly incompatible?
Igor Korkhov
The CLR checks the full version number, not just major+minor.
Hans Passant
Hmm, I thought that it didn't check for the full version number when it comes to privately deployed assemblies, was I wrong? Jeffrey Richter wrote about that: "To accomplish this versioning support, the CLR willexpect that a version of an assembly that fixes one or more bugs will have the same major/minor version, and the build/revision numbers will indicate a servicing version containing thebug fix(es). When loading an assembly, the CLR will automatically find the latest installed servicingversion that matches the major/minor version of the assembly being requested." Isn't it correct?
Igor Korkhov
* does not produce automatic version increment but automatic version change, because the number is random. This way I can not check if a version is older or newer than other and using creation dates is not reliable due a lot of reasons.
SoMoS
@SoMoS - It is not random. The build number is the number of days since 1/1/2000. The revision number is derived from the time.
Hans Passant
@nobugz: "The revision number is derived from the time" - revision numbers is equal to the number of seconds since midnight divided by two
Igor Korkhov
Adding new stuff to an assembly maintains an assembly compatible? In this situation is preferred to maintain the AssemblyVersion?
SoMoS
@SoMoS - it depends but that would be uncommon. The failure scenario is an updated app trying to a public class that doesn't exist in an old version of the DLL.
Hans Passant
A: 

If you want an auto incrementing number that updates each time a compilation is done, you can use VersionUpdater from a pre-build event. This has the advantage of more control than the default numbering mechanism described on MSDN.

Well, I really want that the number is updated when the compilation do something, not when the build process find the code up to date.
SoMoS