In Suzanne Cook's .NET CLR Notes she talks about the dangers of the "LoadFrom" context. Specifically,
- 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.
How do you reproduce this behavior with deserialization, but without explicitly loading two different versions of the assembly?
I've created a Console application, A.exe, which indirectly loads (via `Assembly.LoadFrom) and calls (via reflection) code from a class library, B.dll.
Assembly.LoadFrom
on.A.exe
B.dll
Output
Here's what is happening:
formatter.Deserialize(ms)
is made, it uses the information stored in the MemoryStream to determine what type of object it needs to create (and which assembly it needs in order to create that object).(T)formatter.Deserialize(ms)
fails.Additional notes:
Assembly.Load
, then instead of anInvalidCastException
, there would be aSerializationException
with the message Unable to find assembly 'B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.DeepClone
code I've shown seems to be one of the more popular ways to do a deep clone on an object. See: Deep cloning objects in C#.So, from any code that was loaded into the "LoadFrom" context, you cannot use deserialization successfully (without jumping through additional hoops to allow the assembly to successfully load in the default "Load" context).