简体   繁体   中英

Assembly.LoadFrom and dependencies

I've been trying to setup a plugin system using Assembly.LoadFrom() that dynamically loads dlls in a sub-folder of the .exe's directory.

I have one interface lib referenced by both the .exe and the plugin. Once the build is done i copy the plugin dll to the sub-folder.

Differents plugins might have libs in common, so i would like to gather those dependencies next to the .exe.

My understanding is that i have to use the AssemblyResolve event to manually load plugins dependencies from the exe's directory. Is this correct ? Because it seems very cumberstone.

In your case you have two possible scenarios:

1- Your Exe and your Plugin share a reference: In that case the shared referenced is already loaded by the Exe and you don't need to worry about loading it. Even if you try to load it again since it already exists in loaded assemblies it wouldn't get loaded again.

2- Your Exe does not reference the library the plugin references. In this case if the library assembly exists in your subfolder and you use LoadFrom it should try to load the dependant assemblies for you. Now, although your application startup path is the Exe's directory, I don't think the assembly resolve would fail in case you have a direct reference from your plugin to the library. However if it does fail for whatever reason, the .Net framework has the AssemblyResolve to assist you. You just subscribe to that event and have it search the right path(the subfolder) for the library.

It's not really cumbersome. It's just subscribing to a single event. Something like this:

private static Assembly ResolveAssembly(object sender, ResolveEventArgs e)
{
    //The name would contain versioning and other information. Let's say you want to load by name.
    string dllName = e.Name.Split(new[] { ',' })[0] + ".dll";
    return Assembly.LoadFrom(Path.Combine([AssemblyDirectory], dllName));
}

You could register to the AssemblyResolve event, which will fire in case the CLR fails to load the dependencies, or you can use the <probing> element inside your app.config to instruct the CLR to look in these directories as well:

From MSDN :

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>

Solved by using ProcMon.exe. The missing dll was in fact correctly loaded. But it also had dependencies that i didn't copy to the exe folder. The DllNotFoundException had as confusing message as it didn't report the missing dll but rather the failing dll.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM