3

I want to load assemblies dynamically in my app with the AssemblyResolver event, but I don't understand how to do it.

I've saw this tutorial and tried it myself. In tip 3 he wrote:

static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
}
static void Print()
{
    var mainClass = new MainClass();
    mainClass.Print();
}

static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
    return Assembly.LoadFile(@"path to the library");
}

Actually I don't understand how this code should compile at all... The new MainClass() cannot be compiled as it unknown (the type isn't loaded yet), the loading happens at runtime.
If the MainClass was known type, it shouldn't be resolved at all...

How this code should work?

nrofis
  • 8,975
  • 14
  • 58
  • 113
  • i think the `print` is some method just for debugging(such as, call stack), and not mean something contained in the loaded assembly. the ahthor should have given the code in previous chapters. – Lei Yang Apr 24 '17 at 07:33

2 Answers2

1

If compiles because presumably you have a reference to the library with a MainClass type and Print method, even if it is an empty stub without any actual implementation - or just the wrong implementation. It isn't "unknown". If it was unknown, then indeed this code wouldn't compile, and you'd have to use reflection to find the type at runtime, and reflection to instantiate the instance, and reflection to invoke the Print() method (unless there is some well-known interface or base-class you can cast to, or you use dynamic).

That is all you need to compile something: the metadata. In fact, it is relatively common to target "reference libraries" that are exactly that - this is precisely how many of the multi-targeting features in your IDE work.

At runtime, you can override the load to provide the intended library, but to be honest it is usually easier just to deploy the actual library into the probe path(s) of your application (typically: next to the main exe). Also, in your ResolveAssembly method, it would be a good idea to check which assembly is being requested - it could be trying to load something completely unrelated, in which case just leave it alone.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
0

If you want to load an assembly of which you don't know the content (and then use reflection to instantiate its classes), you can simply use Assembly.Load() if you have its fullname (name, version, culture and public key token if present), or Assembly.LoadFrom if you have its pathname.

The AssemblyResolve is used to "redirect" the loading of an assembly that is "known" at compile-time but that at runtime time must be loaded from a specific path. You can clearly use it to "bait and switch" the assembly (at compile time you have an assembly, at runtime you load a different assembly that implements the same classes).

xanatos
  • 109,618
  • 12
  • 197
  • 280