我有一个C#应用程序,我们称之为App.exe。它引用了一个名为A.dll的DLL,后者又引用了另一个DLL,即B.dll。然而,它们被引用的方式有点不同。在A.dll的代码中,它直接引用了B.dll(通过转到Project> References> Add B.dll)。但是,我的App.exe具有使用Assembly.Load()等在运行时加载A.dll的代码。
所以回顾一下,
App.exe ----(运行时加载)---> A.dll ----(直接参考)---> B.DLL
所有这三件事(App.exe,A.dll和B.dll)都在同一个目录中,比方说ExeDir。现在我想要做的是,将A.dll和B.dll放在ExeDir的子目录中。我可以通过使用指定A.dll路径的App.config文件并要求App.exe从该路径加载A.dll来完成此操作。到目前为止一切都很好。
然而问题是,当我这样做时,.NET给我一个错误,说它无法找到与A.dll在同一目录中的B.dll。如果我将其移回原始目录(与App.exe相同的目录),那么它可以正常工作。这意味着,我可以将A.dll放在子目录中,但B.dll需要位于原始目录中。
有什么方法可以将两个DLL保存在子目录中?
答案 0 :(得分:10)
在app.config中添加<probing>
元素:
http://msdn.microsoft.com/en-us/library/823z9h8w.aspx
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
答案 1 :(得分:7)
您可以通过为当前AppDomain的AppDomain.AssemblyResolve
事件提供事件处理程序来手动解析B.DLL
程序集。
currentDomain.AssemblyResolve += ResolveLostAssemblies;
然后提供ResolveEventHandler
的实现:
private Assembly ResolveLostAssemblies(object sender, ResolveEventArgs args)
{
// Find the assembly referenced by args.Name, load it dynamically, and return it.
}
我发现这可以最大程度地控制加载哪些程序集以及何时加载。它尤其适用于您的应用程序是 pluggable 且每个插件都位于“plugins”文件夹(不一定是应用程序目录)的子目录中的情况。从技术上讲,程序集甚至不必是使用此方法的物理文件。虽然D Stanley's method通常被认为更为标准。
答案 2 :(得分:1)
一种选择是尝试在全局程序集缓存中注册程序集。 http://msdn.microsoft.com/en-us/library/4a9t8a9a.aspx但这可能不是D Stanley的回答。