简体   繁体   English

Assembly.LoadFrom和依赖项

[英]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. 我一直在尝试使用Assembly.LoadFrom()设置插件系统,该系统将dll动态加载到.exe目录的子文件夹中。

I have one interface lib referenced by both the .exe and the plugin. 我有一个.exe和插件引用的接口库。 Once the build is done i copy the plugin dll to the sub-folder. 构建完成后,我将插件dll复制到子文件夹。

Differents plugins might have libs in common, so i would like to gather those dependencies next to the .exe. Differents插件可能具有相同的库,因此我想在.exe旁边收集那些依赖项。

My understanding is that i have to use the AssemblyResolve event to manually load plugins dependencies from the exe's directory. 我的理解是,我必须使用AssemblyResolve事件从exe目录中手动加载插件依赖项。 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. 1-您的Exe和您的插件共享一个参考:在这种情况下,Exe已经加载了共享的参考,您不必担心加载它。 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. 2-您的Exe不引用插件引用的库。 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. 在这种情况下,如果库程序集存在于子文件夹中,并且您使用LoadFrom则它应尝试为您加载从属程序集。 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. 现在,尽管您的应用程序启动路径是Exe的目录,但我不认为万一您从插件直接引用库时,程序集解析不会失败。 However if it does fail for whatever reason, the .Net framework has the AssemblyResolve to assist you. 但是,如果由于任何原因而失败,.Net框架都可以通过AssemblyResolve来为您提供帮助。 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: 您可以注册到AssemblyResolve事件,以防CLR无法加载依赖项时触发该事件,也可以在app.config使用<probing>元素来指​​示CLR也可以在这些目录中查找:

From MSDN : 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. 通过使用ProcMon.exe解决。 The missing dll was in fact correctly loaded. 丢失的dll实际上已正确加载。 But it also had dependencies that i didn't copy to the exe folder. 但是它也具有我没有复制到exe文件夹的依赖项。 The DllNotFoundException had as confusing message as it didn't report the missing dll but rather the failing dll. DllNotFoundException的消息令人困惑,因为它没有报告丢失的dll,而是报告了失败的dll。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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