需要一种方法来引用同一个第 3 方 DLL 的 2 个不同版本 [英] Need a way to reference 2 different versions of the same 3rd party DLL

查看:24
本文介绍了需要一种方法来引用同一个第 3 方 DLL 的 2 个不同版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 2 个项目的解决方案:Proj1 和 Proj2,其中 Proj1 是启动项目.

Proj1 引用 Proj2(为了调用 Proj2 的类),并且它的现有代码也引用了名为 A 的第 3 方 DLL,版本为 1.0.0.0.

Proj2 引用了相同的第 3 方 DLL A,但它在 2.0.0.0 版中引用了它,因为该项目中的类需要更新的实现,而 1.0.0.0 中没有.

到目前为止,我已经尝试了以下方法:1. 引用 A 时将特定版本"切换为 true2.在Proj2中添加了一个名为v2Folder"的文件夹,并在其中添加了一个v2.0.0.0,将其复制到输出目录"设置为始终复制3.在app.config中添加了探测路径"指向v2.0.0.0 DLL所在的子文件夹

我想要的是在普通in文件夹中看到A v1.0.0.0,在inv2Folder中看到A v2.0.0.0,我希望当我运行我的Proj1.exe时,Proj1的旧代码还是会调用A v1.0.0.0的方法,调用Proj2实现的只会调用A v2.0.0.0的方法.

问题是,当我构建我的解决方案时,v1.0.0.0 被 v2.0.0.0 取代,构建日志中有类似无法解决"A、版本=2.0.0.0、文化之间的冲突=neutral, PublicKeyToken=blah"和A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=blah".任意选择A, Version=2.0.0.0, Culture=neutral, PublicKeyToken=blah".

有人可以帮忙吗?

解决方案

即使两个dll版本的public token相同,也是可以实现的.

以下是实现此目的的步骤:

  • 确保将两个版本的dll复制到目标目录
    • 添加两个dll作为项目的内容项
    • 为两者启用本地副本
  • 确保在编译时会引用两个版本的dll
    • 在项目中添加两个dll作为引用
    • 禁用两者的本地副本

仅添加引用是不够的,因为只会复制较新的引用(即使您为两者都启用了本地复制).这给出了这样的项目树:

  • 确保在编译时可以区分两个版本的dll
    • 为至少一个引用添加别名

  • 使用外部别名引用代码中的库(参见@drf

    此时您可以编译,但在运行时仍然存在问题.要解决这些问题:

    • 禁用自动

      • 编辑 app.config 以添加 assemblyBinding.
        • assemblyIdentity 是相关的 dll.
        • bindingRedirect 将版本范围 (oldVersion) 映射到固定版本 (newVersion).
        • codeBase 将固定的 version 映射到文件路径 (href).

      bindingRedirect newVersioncodeBase version 必须匹配并匹配使用的 dll 的版本.

      这里,都是关于

      这是程序输出:

      此黑客源代码可在此处获得.

      正如 sharpiro 评论的那样,项目构建时仍然有警告,这与 这个 msbuild 错误有关,这个答案是一种解决方法.

      I have a solution with 2 projects: Proj1 and Proj2, where Proj1 is the startup project.

      Proj1 references Proj2 (in order to call Proj2's class) and it has existing code that also references a 3rd party DLL called A, versioned at 1.0.0.0.

      Proj2 references the same 3rd party DLL A, but it references it at version 2.0.0.0, since the class in this project needs newer implemenation that was not available in 1.0.0.0.

      So far I've tried the following: 1. Switched "Specific Version" to true when referencing A 2. Added a folder called "v2Folder" in Proj2 and added A v2.0.0.0 to it, set its "Copy to Output Directory" to Copy Always 3. Added "probing path" to app.config to point to the sub-folder with the v2.0.0.0 DLL

      What I want is to see A v1.0.0.0 in the normal in folder, and A v2.0.0.0 in inv2Folder, and I expect that when I run my Proj1.exe, Proj1's old code will still call A v1.0.0.0's methods, and only call A v2.0.0.0's methods when calling what is implemented by Proj2.

      The problem is, when I build my solution, v1.0.0.0 got replaced by v2.0.0.0, the build log has something like "No way to resolve conflict between "A, Version=2.0.0.0, Culture=neutral, PublicKeyToken=blah" and "A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=blah". Choosing "A, Version=2.0.0.0, Culture=neutral, PublicKeyToken=blah" arbitrarily.".

      Can someone help?

      解决方案

      It's achievable even if the two dll versions have the same public token.

      Here the steps to achieve this:

      • Ensure that the two version of the dll will be copied to the target directory
        • Add the two dll's as content items of the project
        • Enable local copy for both
      • Ensure that the two version of the dll will be referenced at compile time
        • Add the two dll's in the project as references
        • Disable local copy for both

      Just add the references is not enough, since only the newer one will be copied (even if you enable local copy for both). This give a project tree like this:

      • Ensure that the two version of the dll can be distinguished at compile time
        • Add an alias for at least on of the references

      • Reference the libraries in the code using extern alias (see @drf response)

      At this point you can compile but you still have problems at run-time. To fix those:

      • Edit app.config to add an assemblyBinding.
        • assemblyIdentity is the concerned dll.
        • bindingRedirect map a version range (oldVersion) to a fixed version (newVersion).
        • codeBase map a fixed version to a file path (href).

      bindingRedirect newVersion and codeBase version must match and match the version of the used dll.

      Here, it's all about the dll assembly version, not the file version

      Here is the program output:

      This hack source code is available here.

      Edit: As sharpiro commented, there is still a warning when the project is built, this is related to this msbuild bug for witch this answer is a workaround.

      这篇关于需要一种方法来引用同一个第 3 方 DLL 的 2 个不同版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆