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

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

问题描述

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



Proj1引用Proj2(以调用Proj2的类)。具有现有的代码,该代码还引用了版本为1.0.0.0的名为A的第三方DLL。



Proj2引用了相同的第三方DLL A,但它引用的版本为2.0.0.0,因为该项目中的类需要1.0中没有的较新的实现。 0.0。



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



我想要的是在普通的\bin\文件夹中看到一个v1.0.0.0,一个v2。 \bin\v2Folder中的0.0.0,我希望当我运行Proj1.exe时,Proj1的旧代码仍将调用A v1.0.0.0的方法,并且仅在调用什么时调用A v2.0.0.0的方法是由Proj2实现的。



问题是,当我构建解决方案时,v1.0.0.0被v2.0.0.0取代了,构建日志中有类似无法解决 A,版本= 2之间的冲突。 0.0.0,文化=中性,PublicKeyToken = blah和 A,版本= 1.0.0.0,文化=中性,PublicKeyToken = blah。



有人可以帮忙吗?

解决方案

即使两个dll版本具有相同的公共令牌,也是可以实现的。



请按照以下步骤操作:




  • 确保将dll的两个版本复制到目标目录


    • 将两个dll添加为项目的内容项

    • 为这两个都启用本地副本


  • 确保在编译时引用两个版本的dll


    • 在其中添加两个dll该项目作为参考

    • 禁用两者的本地副本




仅添加引用是不够的,因为仅会复制较新的引用(即使您同时为两个引用启用了本地复制)。
这样会得到一个项目树:






  • 确保可以在编译时区分两个版本的dll


    • 为至少其中一个引用添加别名







  • 使用extern别名引用代码中的库(请参阅@drf



    这时可以编译,但是在运行时仍然有问题。
    要解决这些问题,请执行以下操作:




    • 禁用自动




      • 编辑 app.config 以添加 assemblyBinding


        • assemblyIdentity 是相关的dll。

        • bindingRedirect 将版本范围( oldVersion )映射到固定版本( newVersion )。

        • codeBase 将固定的版本映射到文件路径( href )。




      bindingRedirect newVersion codeBase版本必须匹配并匹配使用的dll的版本。



      在这里,有关dll程序集的全部内容



      以下是程序输出:



      < img src = https://i.stack.imgur.com/GxVjG.png alt =控制台输出>



      此hack源代码可以在此处



      编辑:正如 sharpiro 所评论的那样,当项目处于内置,这与此msbuild错误有关,这个答案是一种解决方法。 / p>

      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 \bin\ folder, and A v2.0.0.0 in \bin\v2Folder, 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.

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

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