簡體   English   中英

需要一種方法來引用同一個第 3 方 DLL 的 2 個不同版本

[英]Need a way to reference 2 different versions of the same 3rd party DLL

我有一個包含 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 時將“特定版本”切換為 true 2. 在 Proj2 中添加了一個名為“v2Folder”的文件夾並將 A v2.0.0.0 添加到其中,將其“復制到輸出目錄” " to Copy Always 3. 向 app.config 添加了“探測路徑”以指向帶有 v2.0.0.0 DLL 的子文件夾

我想要的是在普通\\bin\\文件夾中看到A v1.0.0.0,在\\bin\\v2Folder中看到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、文化 = 中性、 PublicKeyToken=blah”和“A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=blah”。任意選擇“A, Version=2.0.0.0, Culture=neutral, PublicKeyToken=blah”。

有人可以幫忙嗎?

即使兩個dll版本具有相同的公共令牌也是可以實現的。

這是實現此目的的步驟:

  • 確保將兩個版本的dll復制到目標目錄
    • 添加兩個dll作為項目的內容項
    • 為兩者啟用本地副本
  • 確保在編譯時會引用兩個版本的dll
    • 在項目中添加兩個dll作為引用
    • 為兩者禁用本地副本

僅添加引用是不夠的,因為只會復制較新的引用(即使您為兩者都啟用了本地復制)。 這給出了一個這樣的項目樹:

項目樹

  • 確保在編譯時可以區分兩個版本的dll
    • 為至少一個引用添加別名

別名字段位置

  • 使用 extern 別名引用代碼中的庫(請參閱 @drf響應

示例代碼

此時您可以編譯,但在運行時仍然存在問題。 要解決這些問題:

自動生成綁定重定向復選框位置

  • 編輯app.config以添加assemblyBinding
    • assemblyIdentity是相關的 dll。
    • bindingRedirect將版本范圍 ( oldVersion ) 映射到固定版本 ( newVersion )。
    • codeBase將固定version映射到文件路徑 ( href )。

bindingRedirect newVersioncodeBase version必須匹配並且匹配使用的 dll 的版本。

在這里,都是關於dll 程序集版本,而不是文件版本app.config 示例

這是程序輸出:

控制台輸出

在此處獲得此 hack 源代碼。

編輯:正如sharpiro所評論的,在構建項目時仍然會出現警告,這與女巫的這個msbuild錯誤有關,這個答案是一種解決方法。

使用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 參考。)

將 3rd party dll version 2.0 重命名為 A_2.dll,並添加對重命名的 dll 的引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM