【问题标题】:Dependency Hell on .NET (C#) Application Plugin.NET (C#) 应用程序插件上的依赖地狱
【发布时间】:2019-10-16 11:22:40
【问题描述】:

我目前正在为第 3 方 WindowsForms 应用程序开发一个插件,它将与其他插件共存。请注意,我无法控制基础应用程序使用的源或文件(例如 dll 文件、配置文件等),也无法控制可能在运行时加载的其他插件。

让我们想象一下,在我之前加载的其他插件之一加载了对库 A 的 1.0 版(“A.dll”)的依赖项。如果我的插件尝试加载库 A 的 2.0 版(也称为“A.dll”),我会立即看到经典的“System.IO.FileLoadException”。

在深入了解依赖地狱的主题后,我看到了一些选项(例如 herehere )。然而,所有这些选项似乎都集中在独立应用程序上,开发人员通常可以完全控制这些应用程序,这需要加载同一库的两个版本(可能是出于遗留支持或任何其他奇怪的原因)。由于插件环境,这些解决方案似乎不适用于我的案例。此外,他们通常要求:

  • 在 GAC 中插入程序集,AFAIK 需要在最终用户的计算机上具有管理权限,而我没有;
  • 控制基础应用程序的配置文件 (*.exe.config),我没有。

谁能帮我找出一种方法来使用一个新版本的库,该库也被另一个插件用作旧版本,记住我描述的限制

【问题讨论】:

    标签: c# .net winforms plugins dependency-management


    【解决方案1】:

    如果您自己提供库 A.dll 2.0 版,您可以将其重命名为 A.2.0.dll 并引用它。

    【讨论】:

    • 我确实可以控制库 A.dll,这是我现在的首选:简单有效。但是,它需要我为每个版本重命名库(为了清楚起见,我简化了问题:我的库 A.dll 对应于一堆 dll 文件)。在选择这个选项之前,我只想知道是否有其他的,也许更优雅的选择来实现这一点。
    • @PedroPinheiro 由于所有插件都在同一个目录中,并且您不能在 GAC 中放置任何内容,因此我认为没有其他选项可以让您使用同一文件的多个版本。
    • 我们有一个依赖于流行框架(如 Mono.Cecil)的 VS 扩展,它可能会被其他 VS 扩展加载。我们确实在一些用户的生产中遇到了冲突。我们的选择是将其重命名为 Mono.Cecil.4NDepend.dll ,NDepend 是我们的产品。使用 4YourProduct 后缀比使用版本后缀更好 1)您重命名第三方一次 2)谁知道是否没有版本冲突
    • 感谢大家的帮助。我在我的项目中成功采用了这种重命名策略,我可以确认它解决了我最初的问题。
    【解决方案2】:

    您可以处理事件 AppDomain.AssemblyResolve 来控制使用哪个程序集,具体取决于哪个程序集尝试加载它。对我来说似乎是一个 hack,但可能没有干净的方法来解决这个问题。

    【讨论】:

    • 我同意你的观点,这似乎是一个 hack。但是,AppDomain.AssemblyResolve 应该由应用程序上的每个插件处理,不是吗?这可能会造成问题,因为我无法控制应用程序上的其他插件,也无法强制它们使用这种方法......这就是为什么我更倾向于使用 MarTim 提出的解决方案,即使这也不是一个理想的解决方案......
    • AFAIK 其他程序集与您的程序位于同一个 appdomain 上,所以我认为您是安全的……您只需确保您的插件是否请求程序集(或者您的插件是否在请求程序集)请求版本)返回正确的程序集。如果您忽略所有其他调用,则将为应用程序的其余部分重新调整默认版本的 assemlby。
    猜你喜欢
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 2012-04-08
    • 2015-12-21
    相关资源
    最近更新 更多