【问题标题】:Reference a DLL from another DLL从另一个 DLL 引用一个 DLL
【发布时间】:2012-02-16 12:22:51
【问题描述】:

我有一个 C# 应用程序,我们称之为 App.exe。它引用了一个名为 A.dll 的 DLL,而 A.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 都保存在子目录中?

【问题讨论】:

    标签: c# dll reference


    【解决方案1】:

    在您的 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>
    

    【讨论】:

    • 感谢 D Stanley 的回复。但我在这里有点茫然。你能告诉我我到底应该在这里做什么吗?只是用装配路径指定这个元素?
    • 是的,相对于您的 EXE。例如,在 MSDN 示例中,活页夹将默认搜索 BIN 文件夹,但也会搜索 bin2 文件夹、bin2\subbin 文件夹和 bin3 文件夹。将 bin;bin2\subbin;bin3 替换为 A.dll 和 B.dll 所在的文件夹(相对于 EXE)。请注意,如果 A.dll 包含在探测路径中,则不再需要指定路径。
    • 谢谢斯坦利,我让它工作了!不过,这是我的错,我没有在这里解释我的完整问题。我想要在不同文件夹中的 DLL 的原因是我可能有几个不同的 A.dll(内容不同),并且每个都可能引用 B.dll。所以我想实现更安全的代码,这样如果不同的 A.dll 想要引用 B.dll ,内部也可能有所不同。但是好像做不到。还是,谢谢!你回答了我原来的问题。
    【解决方案2】:

    一种选择是尝试在全局程序集缓存中注册您的程序集。 http://msdn.microsoft.com/en-us/library/4a9t8a9a.aspx 但这可能不如 D Stanley 的回答。

    【讨论】:

    • GAC 是邪恶的 :) 不要使用它。
    【解决方案3】:

    您可以通过为当前 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.
    }
    

    我发现这可以最大程度地控制加载哪些程序集以及何时加载。它特别适用于您的应用程序可插入并且每个插件都位于“插件”文件夹(不一定是应用程序目录)的自己的子目录中的情况。从技术上讲,使用这种方法的程序集甚至不必是物理文件。虽然D Stanley's method 通常被认为更标准。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多