我一直在尝试使用Assembly.LoadFrom()设置一个插件系统,该系统会动态地将dll存储在.exe目录的子文件夹中。
我有一个由.exe和插件引用的接口库。 构建完成后,我将插件dll复制到子文件夹。
Differents插件可能有共同的库,所以我想收集.exe旁边的依赖项。
我的理解是我必须使用AssemblyResolve事件从exe目录手动加载插件依赖项。它是否正确 ?因为它看起来很麻烦。
答案 0 :(得分:2)
在您的情况下,您有两种可能的情况:
1-您的Exe和您的插件共享一个参考:在这种情况下,Exe已经加载了共享引用,您不必担心加载它。即使您尝试再次加载它,因为它已经存在于已加载的程序集中,它也不会再次加载。
2-您的Exe不引用插件引用的库。在这种情况下,如果库程序集存在于子文件夹中并且您使用LoadFrom
,它应该尝试为您加载依赖程序集。现在,虽然您的应用程序启动路径是Exe的目录,但我不认为如果您从插件直接引用到库,则程序集解析将失败。但是,如果它因任何原因失败,.Net框架会有AssemblyResolve
来帮助您。您只需订阅该事件并让它搜索库的正确路径(子文件夹)。
它不是很麻烦。它只订阅了一个单一的活动。像这样:
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));
}
答案 1 :(得分:1)
您可以注册AssemblyResolve
事件,以便在CLR无法加载依赖项时触发,或者您可以使用<probing>
中的app.config
元素来指示CLR查看这些目录:
来自MSDN:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
答案 2 :(得分:0)
使用ProcMon.exe解决。 丢失的dll实际上是正确加载的。但它也有依赖,我没有复制到exe文件夹。 DllNotFoundException有一个令人困惑的消息,因为它没有报告丢失的dll而是报告失败的dll。