Assembly.Load(File.ReadAllBytes(@"SomeFolder\MyLib.dll"));
in a loop. All copies will have their code base set to the currently executing assembly. Code base specifies the physical location of an assembly. By executing the following line
Assembly.LoadFrom(@"SomeOtherFolder\MyLib.dll");
we load another copy but this time from completely different location. Let’s add one more:
Assembly.Load("MyLib");
In this way we end up with several copies and 3 different code bases inside of the same AppDomain. This happens because each assembly is loaded into different load context. You can read about that here. Why is it like that? To be honest I’ve found no clear explanation. Some Microsoft bloggers mention that this makes order independent loading possible. But that’s it. From my perspective that’s not much to justify the fact that multiple copies of the same assembly can be loaded into the same AppDomain which is very often dangerous.
The main problem is that the runtime treats types in all copies as completely different types. This means that if you create an object of type MyClass using the type definition from the assembly loaded by Load method you won’t be able to pass it to a method that takes MyClass as a parameter but is defined in the assembly loaded by LoadFrom method. If something like that happens you get InvalidCastException which is hard to believe in because VS debugger clearly shows that the type of the parameter is correct :). It’s only when you dig deeper and check the assembly where the type comes from when you find out that they are from 2 different assemblies. This can be very confusing and hard to debug. Even if there is a valid reason behind this feature it would be great if I could run loader/runtime in some kind of strict mode where duplicates are not allowed and a meaningful exception is thrown when an assembly is requested to be loaded more than once. I can see more and more code that is loaded dynamically at runtime and this feature would be very useful.