Reputation: 5514
I just came across an issue with assembly references I haven't seen before. In my usual production code, my loader application loads the main application assembly (and other references) by passing the raw bytes to Assembly.Load
and then calling the entry point.
Today I needed to have the main application dynamically load another reference (henceforth called the 'dll'), which contains a class that inherits from a base class in the main program. This works fine when running the main application directly. When running it through the loader, the main application loads the dll just fine, but it doesn't seem to know that the currently loaded main application is the same as the one the dll references. So casting to the base class obviously won't work. And I'm stuck.
I'm assuming the main application assembly is losing it's identity somehow.
Here's some code that illustrates the issue:
// main application
namespace Program1
{
public class BaseClass { }
class Program
{
static void Main( string[] args )
{
string s = "Library1.Class1, Library1";
var t = Type.GetType( s, true );
Debug.Assert( t.IsSubclassOf( typeof( BaseClass ) ) );
}
}
}
// dll
namespace Library1
{
public class Class1 : Program1.BaseClass { }
}
// loader
class Program
{
static void Main( string[] args )
{
var bytes = File.ReadAllBytes( "Program1.exe" );
var asm = Assembly.Load( bytes );
var e = asm.EntryPoint;
e.Invoke( null, new object[] { null } );
}
}
When running Program1 directly it works, when running it through the loader the assert fails.
So, could anyone explain what's going on here - and if there is a possible way around it?
Upvotes: 1
Views: 49
Reputation: 15151
If (let's call dllA and dllB your libraries), dllA has a reference to dllB and you load dllA and it doesn't crashes it means .net has autoresolved and loaded dllB.
Then when you load again dllB it's another assembly, and then the types don't match, I ran myself a lot of times with that situation with a dll-loading system, at the end is better to add the referenced libraries (in this case dllB) in the .exe folder and let the system load it automatically when you load dllA.
Another option if you need the reference to the library is to attach to the AssemblyResolve event before loading DllA, then when you load it the event will fire requiring you to load DllB and thus you can store the reference to the library.
Upvotes: 1