我有一个包含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“。”。
有人可以帮忙吗?
答案 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版本具有相同的公共令牌也可以实现。
以下是实现此目的的步骤:
仅添加引用是不够的,因为仅会复制较新的引用(即使您同时为两个引用启用了本地复制)。 这给出了一个这样的项目树:
这时您可以编译,但是在运行时仍然有问题。 要解决这些问题:
app.config
以添加assemblyBinding
。
assemblyIdentity
是相关的dll。bindingRedirect
将版本范围(oldVersion
)映射到固定版本(newVersion
)。codeBase
将固定版本映射到文件路径(href
)。 newVersion
和codeBase
必须与使用的dll版本匹配。
这是关于the dll assembly version, not the file version的全部内容
这是程序输出:
此hack源代码可用here。