Whidbey breaking change — Caching binding failures

This is one of the breaking change mentioned in gotdotnet.com’s break change from .Net 1.1 to 2.0

Cache load failures in order to ensure that different app domains do not have different dependency loading success/failure characteristics in domain neutral sharing scenarios




What does it mean?


Say  you call Assembly.Load(”Foo, version=, culture=neutral, publicKeyToken=0123456789abcdef”), you get a FileNotFoundException. You realize that foo.dll should be in GAC but you forget to install it. So you install it (using gacutil.exe or some other mechanism) to GAC. Now you call Assembly.Load(“Foo, version=, culture=neutral, publicKeyToken=0123456789abcdef“) again.


In v1.0/v1.1, the second load will succeed. In Whidbey, the second load will fail.


Installing to GAC is just an example. As long as the first bind failed, the second bind will fail with exactly the same exception.


The caching is done on per AppDomain basis. If you create a new AppDomain and call Assembly.Load() on that app domain, it will succeed.

Comments (8)

  1. David Levine says:

    Will this affect the loading of assemblies from non-GAC locations? For example, if the 1st call to Assembly.Load("foo, blah blah…") fails with FileNotFoundException, and then the correct version of foo is then copied to a location such as the appbase that would normally satisfy a bind, will the next call to Assembly.Load("foo, …") succeed?

    I think this may boil down to what is meant by domain neutral sharing and why that affects this situation. My recollection is that this involves sharing the JITted code, runtime tables, etc., (but not per-appdomain data) and that the domain-neutrality policy is determined by the hosting process, not by the managed app itself. I would expect that if an assembly is domain neutral then all appdomains would bind to the same assembly if the binding policy for that appdomain resolves to the same assembly identity for a given Load. However, I don’t see why that requires that a failure be cached so that once it fails it can never succeed.

    Perhaps you could expand on domain neutrality and how it relates to the issue you presented here. Thanks.

  2. Yes, the second Assembly.Load will fail, as I stated in the main text

    "As long as the first bind failed, the second bind will fail with exactly the same exception. "

    I will talk about domain neutral in the future (or ask someone else more insightful to talk about it).

    For a short answer. If you enabled domain neutral sharing, at some point, loader will mark certain assemblies as domain neutral and share them across appdomains. There are some assumption loader made when decide whether the assembly can be domain neutral or not. One of them is that its dependencies can be found or found. If this is changing on the fly, loader’s assumptions are broken, and you end up with an invalid sharing.

  3. Chris Brumme told me that he discussed domain neutral assemblies here in his AppDomain blog:


    It goes into great detail about the design of domain neutral assemblies: what is domain neutral assemblies, why it is introduced, what are its advantage and disadvantage.

    This caching binding failure behavior is more about how domain neutral assemblies is implemented, and is not totally covered by Chris’s blog.