Collectible Assembly in non-collectible AssemblyLoadContext
.NET incorrectly allowed garbage-collectible assemblies to resolve into a non-collectible AssemblyLoadContext. In some cases, this lead to runtime crashes or unexpected NullReferenceException exceptions. This change prevents the incorrect behavior by throwing an exception when the AssemblyLoadContext.Load(AssemblyName) or AssemblyLoadContext.Resolving event returns a collectible Assembly and the AssemblyLoadContext is non-collectible.
Returning a collectible Assembly in the AssemblyLoadContext.Load(AssemblyName) override or the AssemblyLoadContext.Resolving event of a non-collectible AssemblyLoadContext doesn't cause any exceptions to be thrown.
Returning a collectible Assembly in the AssemblyLoadContext.Load(AssemblyName) override or the AssemblyLoadContext.Resolving event of a non-collectible AssemblyLoadContext throws a System.IO.FileLoadException with a NotSupportedException as the inner exception.
Type of breaking change
This change can affect binary compatibility.
Reason for change
This change fixes a bug. The collectible Assembly would be garbage-collected while the AssemblyLoadContext that has a reference to it is alive for the rest of the process lifetime. If the code running in that context references anything from that
Assembly after it's collected, it would crash the runtime or result in a NullReferenceException, AccessViolationException, or other kinds of bad behavior.
Don't return collectible assemblies in AssemblyLoadContext.Load(AssemblyName) or the AssemblyLoadContext.Resolving event of a non-collectible AssemblyLoadContext. A possible workaround is to change the
AssemblyLoadContext to be collectible by passing
true for the
isCollectible parameter in its constructor, and then keep a reference to that
AssemblyLoadContext forever to make sure it's never collected.
- System.Runtime.Loader.AssemblyLoadContext.Resolving event