When it rains it pours. Twice today folks came looking when unexpected behaviors
occured after an SDK upgrade.
If you're using a versioning scheme, always ask yourself, what version of my assembly
has been loaded into this AppDomain? It's even more important to be aware (and
not to Program
By Coincidence) when using the GAC.
Digging into the problem showed that the wrong version was being loaded - an older
version from the GAC due to an incorrect bindingRedirect.
A few tools to be aware of and WHAT they tell you about Assembly Binding:
-
Binding before it happens: ILDASM or Reflector will
tell you what your assembly wants (what it was compiled against)
-
Binding as it happens: Fusion (the Assembly
Binding Log Viewer) will show you all assembly binds if you set
the HKLM\Software\Microsoft\Fusion\ForceLog registry value to 1
-
Binding after it happens: Process
Explorer will tell you what DLL (assembly) is loaded in memory and from where
it came.
In this case, a little command line showed me:
C:\>gacutil /l | find /i "Corillian" | more
<snip>
Corillian.Thingie.Whatzit, Version=3.1.0.39, Culture=neutral, PublicKeyToken=xx
Corillian.Thingie.Whatzit, Version=3.1.1.31, Culture=neutral, PublicKeyToken=xx
Ah! There's an older version in the GAC, probably supporting another Web on this box.
Our ASP.NET site was compiled against this (says Reflector) and we confirm the wrong
one was loaded with Process Explorer. But, we need a bug fix from the new version
and can't recompile, so, in our Web.config we added:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Corillian.Thingie.Whatzit"
publicKeyToken="xx"
culture="neutral" />
<bindingRedirect oldVersion="3.1.0.39" newVersion="3.1.1.31"
/>
</dependentAssembly>
</assemblyBinding>
</runtime>
Now when our ASP.NET apps asks for 3.1.0.39, instead it gets 3.1.1.31.
Note that our assembly must be strongly-named for this to work.
Read: Be aware of your DLLs and who's loading them - know about assembly binding redirects