Assembly Version numbers, signed assemblies Why do I get a FileLoadExceptions

1.5k views Asked by At

My Problem:

I have a signed assembly A.dll that it versioned as 1.0.0.0 I have another assembly (lets say B.dll) that references A.dll.

Once both assemblies both assemblies load fine without any problem. Now if the version for A.dll changes to 1.0.0.1 and is recompiled Does B.dll have to be recompiled?

I asking because I have this exact scenario where after A.dll had it's version changed I now receive the following Exception trying to load B.dll:

Unhandled Exception: System.IO.FileLoadException: 
    Could not load file or assembly A, Version=1.0.0.0, 
    Culture=neutral, PublicKeyToken…

This makes me think that the answer to this question is always yes. However I have another example where I have two assemblies that have the exact scenario described above and I do not have any problem loading the assemblies.

What scenario/conditions cause this exception? If anyone can offer some insight to this it would be greatly appreciated. Thanks.

2

There are 2 answers

2
Lars Kemmann On

Whether or not the assembly A is signed does not necessarily matter. Did you compile with 'Specific Version = true' on project B's assembly reference to A? If so, then the CLR will use strict rules to determine whether a given version of A is acceptable. If not, then the CLR will use less strict rules, and you won't need to recompile if A increments its version.

Depending on your environment, you may not be concerned that A will break compatibility in a future version. If it's not a concern for you, then you should change your assembly references to 'Specific Version = false'. (At work, we have both situations: when we depend on a 3rd-party control, for example, we generally force 'Specific Version = true', but when we're consuming an in-house shared component that we will test against the applications which use it, we'll make sure 'Specific Version = false' so we do not need to recompile.)

You can find more information, including how to circumvent this via configuration files when you do have to compile against a specific version but want to redirect bindings later, on MSDN: Redirecting Assembly Versions

Hope that helps!

1
Adam On

When an assembly is strongly named, anything that references it will look for that specific version.

You are correct that 'Specific Version' in Visual Studio doesnt affect the runtime in any way. In fact, the 'Specific Version' basically means "When you run a build, if MSBUILD cannot find the version that was referenced, should the build fail, or just use the next version that can be found on the filesystem?"

If you recompile A, and deploy it, as a partial update (rather than fully rolling out the application), then if there is anything in the application that references the old version, your application may break, unless you still have the old version of A available as well (i.e. you didnt overwrite it).

This is a main reason why some products use the GAC, because it can hold multiple versions of the same DLL without overwriting each other - if you tried to deploy different versions of the same file into your bin folder (assuming they had the same file name, which they typically do), they would overwrite each other, and you'd only end up with 1 of the DLLs in your product!

Another trick you can do is put your 're-versioned' DLLs in a sub-folder under then binary directory, and edit the app.config to tell the runtime where to find them. http://support.microsoft.com/kb/837908

So, to sum up, a strongly named assembly uses more than just the simple name to determine an assembly's identity - changing its version could be thought of as changing its name completely.