【问题标题】:C#: Custom assembly directoryC#:自定义程序集目录
【发布时间】:2010-12-08 07:54:59
【问题描述】:

假设我们有一个包含一个可执行文件和 5 个库的应用程序。通常所有这些都将包含在一个目录中,并且将从那里加载库。

是否可以这样做,例如,我可以将一些库放在一个名为 Lib 的目录中,而将其余库放在一个名为 Lib2 的目录中?这样应用程序目录将只包含可执行文件本身,而其他程序集将包含在各种逻辑目录中。

我该怎么做?而且我想知道如何加载程序集,还想知道如何使应用程序的构建将程序集放在正确的目录中。

【问题讨论】:

  • 是的,你可以,根据 DotNetWill 的回答。但是没有什么收获,您可能会遇到很多维护问题。

标签: c# assemblies assembly-resolution


【解决方案1】:

您可以将其他搜索路径添加到您的 app.config 中,以便加载程序集。例如

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="lib;thirdParty" />
  </assemblyBinding>
</runtime>

您可以查看更多详情here

【讨论】:

  • 太棒了。如果您想要更多路径,您会添加另一个&lt;probing&gt; 标签,还是添加另一个&lt;assemblyBinding&gt; 和另一个&lt;probing&gt; 标签?
  • 另外,有没有办法在运行时添加这个路径?例如,如果它是通过使用某种环境变量或其他东西构建的。
  • 是的,只需添加更多。我不认为你可以在 .Net 2.0+ 的运行时做到这一点,但那里可能是错误的。
  • @Svish 你不要添加更多探测元素;相反,添加更多用分号分隔的目录。 (msdn.microsoft.com/en-us/library/823z9h8w%28v=vs.110%29.aspx)。我已更新答案以包含这些详细信息。
【解决方案2】:

如果您想手动管理从何处获取集合,您有两种可能性:

  1. 处理AppDomain.AssemblyResolve 事件(如 SLaks 所述)。这是代码sn-p:

    static void Main(string[] args)
    {
       ...
       AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
       ...
    }
    
    static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
       string assembliesDir = "your_directory";
       Assembly asm = Assembly.LoadFrom(Path.Combine(assembliesDir, args.Name + ".dll"));
       return asm;
    }
    
  2. 使用您自己的设置创建域(通过设置 AppDomainSetup 对象的ApplicationBasePrivateBinPath 属性)。

因此,如果您想继续在当前域中工作,则必须使用方法 1。

【讨论】:

  • 谢谢!你刚刚救了我,正在谷歌搜索这样的解决方案,但在其他问题的答案中一无所获。这让我很开心:)
  • 我正在尝试使用不在 GAC 中的 Assembly.Load 加载程序集,但失败并且将触发 AssemblyResolve 事件,我正在使用 LoadFrom 从路径加载它。现在这个程序集将在加载上下文中加载,所以它现在使用 Ngen 的图像吗?感谢您的帮助
【解决方案3】:

要自动将程序集复制到您希望它们所在的文件夹中,您可以将所有引用的 Copy Local 设置为 true,并执行构建后步骤将它们移动到子目录中。

或者,您可以将Copy Local设置为false,并将引用的DLL文件添加为项目中相应子目录中的文件,并将Build Action设置为复制到输出目录(这将保留子目录)

让运行时找到它们的最灵活方法是处理AppDomain.AssemblyResolve 事件并使用Assembly.LoadFile 手动加载程序集。您需要某种方式让您的代码知道哪些程序集位于哪些目录中。

【讨论】:

  • AssemblyResolve 可能确实很有帮助。真的不知道那个。关于构建问题,您认为最干净的解决方案是什么?我认为它们看起来都有些凌乱,但我还没有真正尝试过它们,所以我真的不知道:p
  • 如果您正在使用运行时引用,那么复制到本地将无济于事。即,如果您正在使用接口开发,插件模块仅在运行时可用,并且设计时引用在此上下文中不起作用
【解决方案4】:

在您的评论中,您提到在运行时添加路径和位置。是的,你可以,但你必须使用 Assembly.Load(),可能还有反射。

【讨论】:

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