Sep 17, 2008 at 4:13 PM
Edited Sep 17, 2008 at 4:15 PM
The configuration editor for Visual Studio is causing this behavior by being overly eager to assist with assembly load failures.
Here's how it works: app domains have several load contexts, and when resolving assemblies the context in which the executing method's assembly resides determines how types
will be resolved. When you load an assembly (say A) into the LoadFrom context (which happens when you use Assembly.LoadFrom), other assemblies that need to be resolved will use A's codebase as part of the probing path; however, assemblies in the Load context
(like .NET's own assemblies) will be constrained to look for references in the AppDomain's probing path. Also, assemblies in the LoadFrom context can "find" assemblies already loaded in the LoadFrom and Load contexts, but assemblies in the Load context
can only find assemblies already loaded in the Load context. This is a good thing because it makes apps more secure, but can also be the source of seemingly illogical behavior were a framework service invoked by one assembly cannot find the calling assembly.
Most plug-in based architectures suffer from this, and need to deal with the situation by properly configuring assembly resolve events. And by "properly" I really mean help resolve only what's related to the code installing the handler and only while
it's expected to be necessary; an approach that relies on using statements coupled with a disposable class is usually very helpful.
Here's a sample showing this situation:
Assembly 1 - "plug in host"
static void Main(string args)
Assembly assembly = Assembly.LoadFrom(@"..\..\..\ClassLibrary1\bin\debug\ClassLibrary1.dll");
Type type = assembly.GetType("ClassLibrary1.Class1");
IFoo foo = (IFoo)Activator.CreateInstance(type);
Assembly 2 - "plug in"
class Class1 :
public int GetResult()
BinaryFormatter formatter = new
using (Stream memoryStream =
object instance = formatter.Deserialize(memoryStream);
// throws, cannot deserialize itself