Choosing a Binding Context

There are three 'contexts' for assembly binding:

  • Load context
    In general, if the assembly was found by probing in the GAC, a host assembly store (if hosted), or the ApplicationBase / PrivateBinPaths of the AppDomain, the assembly will be loaded in the Load context.
  • LoadFrom context
    In general, if the user provided Fusion a path which was used to find the assembly (and the assembly at that path wouldn't have been found in the Load context), then it's in the LoadFrom context. There are various methods to load by path: LoadFrom(), CreateInstanceFrom(), ExecuteAssembly(), loading an assembly through interop using a codebase, etc.
  • Neither
    If the user generated or found the assembly instead of Fusion, it's in neither context. This applies to assemblies loaded by Assembly.Load(byte[]) and Reflection Emit assemblies (that haven't been loaded from disk). Assembly.LoadFile() assemblies are also generally loaded into this context, even though a path is given (because it doesn't go through Fusion).

Which context is right for you? In general, I strongly recommend that you use the Load context whenever possible. But, of course, there will be times when other contexts are more appropriate for you. So, here are the advantages and disadvantages of each option:

  Advantages Disadvantages
Load
  • Gets the benefits of versioning and policy.
  • Best avoids "Dll Hell." Dll Hell can break your app over time.
  • Dependencies available in the Load context are automatically found.
  • Dependencies in other contexts are not available unless you subscribe to the AppDomain.AssemblyResolve event.
LoadFrom
  • Assemblies can be loaded from multiple paths, not just from beneath the ApplicationBase.
  • Dependencies already loaded in this context will automatically be found.
  • Dependencies in the same dir as the requesting LoadFrom context assembly will automatically be found.
  • If a Load context assembly tries to load this assembly by display name, it will fail to be found by default (e.g., when mscorlib.dll deserializes this assembly).
  • Worse, an assembly with the same identity but at a different path could be found on the probing path, causing an InvalidCastException, MissingMethodException, or unexpected method behavior later on.
  • If an assembly by the same identity is already loaded, you'll get that one back, even if you've specified a path to a different one.
  • It does a FileIOPermission.Read + PathDiscovery demand, or a WebPermission demand on the path/URL specified.
  • The ngen image (if any) won't be used.
  • Can't be loaded as domain-neutral.
  • v1.0 and v1.1 CLR only: won't be affected by policy, so can't be centrally serviced.
Neither
  • Avoids probing costs for loading this assembly.
  • You can load multiple assemblies with the same identity into the same appdomain.
  • You get the bits from the location you specified (as opposed to LoadFrom). Starting in v2, policy/GAC overrides it, however.
  • Nothing can bind to this assembly unless you've subscribed to the AssemblyResolve event.
  • Dependencies can only be loaded from the Load context or using the AssemblyResolve event.
  • Passing this assembly to another AppDomain may become tricky (e.g., when this is a Reflection Emit assembly that hasn't been saved).
  • The ngen image (if any) won't be used.
  • Can't be loaded as domain-neutral.
  • v1.0 and v1.1 CLR only: won't be affected by policy, so can't be centrally serviced.