需要一种方法来引用同一第三方DLL的2个不同版本

时间:2012-07-18 21:57:33

标签: c# dll

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

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

Proj2引用相同的第三方DLL A,但它在版本2.0.0.0引用它,因为此项目中的类需要1.0.0.0中没有的更新实现。

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

我想要的是在普通的\ bin \文件夹中看到一个v1.0.0.0,在\ bin \ v2Folder中看到一个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,Version = 2.0.0.0,Culture =中立,PublicKeyToken = blah“和”A,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = blah“。任意选择”A,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = blah“。”。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:1)

使用extern alias功能可以实现这一点。编译时,请包含DLL文件的别名,例如:

csc.exe ... /reference:AV1=v1.0.0.0/A.dll /reference:AV2=v2.0.0.0/A.dll

(这可以通过更改引用的aliases属性在Visual Studio中设置。)

在cs文件中,您可以使用extern alias来引用名称空间:

extern alias AV1;
extern alias AV2;
// using statements

这允许您独立引用每个版本:

var v1foo = new AV1::Foo();
var v2foo = new AV2::Foo();

对于仅使用其中一个DLL的项目,您可以包含对所需版本的引用。

// ProjA cs file
extern alias AV1;
using Foo = AV1::Foo; // alternately, path to namespace
...
var foo = new Foo(); // from version 1 of library


// ProjB cs file
extern alias AV2;
using Foo = AV2::Foo; // alternately, path to namespace
...
var foo = new Foo(); // from version 2 of library

这允许在同一解决方案中独立引用DLL的两个版本。 (MSDN Reference。)

答案 1 :(得分:0)

将第三方dll版本2.0重命名为A_2.dll,并添加对重命名的dll的引用。

答案 2 :(得分:0)

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

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

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

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

Project tree

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

Aliases field position

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

Example code

这时您可以编译,但是在运行时仍然有问题。 要解决这些问题:

Auto-generate binding redirects checkbox position

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

newVersioncodeBase必须与使用的dll版本匹配。

这是关于the dll assembly version, not the file version的全部内容 app.config example

这是程序输出:

Console output

此hack源代码可用here