Net dll組件版本兼容問題

dll組件版本兼容問題,是生產開發中常常遇到的問題,常見組件兼容問題如:Newtonsoft.Json,log4net等html

爲了節約你們時間,想直接看解決方法的,可直接點擊目錄三、4git

目錄


1.版本兼容問題的緣由緩存

2.解決版本兼容前提markdown

3.指定特定版本bindingRedirect**工具

4.指定某文件夾中的特定版本codeBase**gitlab

 

版本兼容問題的緣由


首先讓咱們簡單瞭解下程序引用的原理:visual-studio

當運行庫試圖解析對另外一個程序集的引用時,就開始進行定位並綁定到程序集的進程。詳細見:運行庫如何定位程序集測試

步驟以下:spa

解決版本兼容前提


簡單瞭解原理之後,常看法決兼容的方法.net

1. 首先了解你要用那個dll,具體版本是什麼,查看版本方法:

1)文件夾裏dll文件,右鍵->屬性

2)解決方案裏引用的dll,右鍵->屬性

 

方法一、指定特定版本**


 利用config的bindingRedirect指向特定版本組件

.config添加節點

<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

 解釋:

項目中全部項目、類庫引用0~10的Newtonsoft.Json版本,最終都指向到10這個版本

經驗:

一、各版本之間是有代碼變化的,若是一個類庫用了某個組件10.0的A10方法,結果指向的8.0,8.0頗有可能尚未A10這個方法,天然項目中用到A10的地方會報錯。調試和查錯誤比較麻煩,編譯器會根據bin下面的dll版本與代碼來匹配調用方法和屬性提示錯誤,或者不提示錯誤。

二、代碼可控的地方,儘量的將版本更新中的廢棄方法改爲高版本的替代方法。

三、通常高版本多數是兼容低版本的方法,指向高版本報錯概率小些,固然也有特殊狀況。

方法二、指定某文件夾中的特定版本


方法一能解決不少項目中出現的版本問題,可是有時候仍是會遇到比較奇怪的兼容問題。

例如:log4net和Memcached.ClientLibrary中的log4net衝突的問題,本文以解決這一版本衝突問題爲例介紹此方法的使用方法。

若是想直接看結果,請點擊解決方法

爲啥會出現log4net版本兼容問題呢?

常見的組件是以name(名稱)、version(版本)、publicKeyToken(公鑰)三個組成,緣由主要是因爲log4net version 1.2.11與1.2.10的publicKeyToken不一樣所致。

可利用VS工具SN -T 組件文件名.dll查看公鑰。

log4net (≥ 1.2.11) 公鑰標記爲 669e0ddf0bb1aa2a

log4net (= 1.2.10) 公鑰標記爲 1b44e1d426115821

看log4net在發展過程當中改過一次身份證,又有好多老版本的組件引用了log4net的低版本致使與高版本兼容問題

 log4net版本兼容問題的樣例

一、建立項目,引用Memcached組件

WebApp爲項目應用層,ClassLibrary爲工具類庫,WebApp引用ClassLibrary項目,ClassLibrary經過nuget引入Memcached.ClientLibrary 1.0組件。

ClassLibrary建立類Testing.cs代碼以下:

    public class Testing
    {
        public static void Init()
        {
            MemcachedClient mc = new MemcachedClient();
        }
    }

 WebApp建立測試頁面,測試代碼以下:

Testing.Init();

二、應用層,引用高版本log4net

WebApp引用log4net 2.0.8

 最終項目狀況是:

 三、運行結果

查看WebApp的bin文件夾下面的log4net版本是2.0.8,而Memcached.ClientLibrary組件用的log4net是1.2.10.0版本,因此報錯了。

注意

若是單獨編譯WebApp,bin下面是版本是2.8.0,若是單獨編譯ClassLibrary類庫,bin下面版本是1.2.10.0

 

處理log4net版本兼容問題

一、bin下面添加log4net1.2.10.0文件夾,並將log4net.dll版本爲1.2.10.0放入到文件夾中,可重命名爲log4net1.2.10.0.dll。

二、config添加

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
        <codeBase version="1.2.10.0" href="bin/log4net1.2.10.0/log4net1.2.10.0.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

 三、結果以下

經驗:

一、文件須要放在bin下面,並單獨創建個文件夾,注意:若不創建文件夾,直接將重命名的log4net1.2.10.0.dll扔到bin下會報錯,應該是探測方法是根據name尋找的。

二、ClassLibrary類庫在單獨編譯的時候,會將高版本的替換成低版本,會有可能報錯,能夠在開發中將其生成的dll不復制到bin下,設置是在引用的dll下右鍵,複製本地設置爲false,操做以下:

三、爲了能把log4net1.2.10.0.dll上傳到gitlab上面,能夠在WebApp創建個相應文件夾,並設置複製到輸出目錄-始終複製,vs編譯時會自動將log4net1.2.10.0/log4net1.2.10.0.dll複製到bin下面

總結


 但願經過此文章,幫助更多的人解決NET組件的版本兼容問題。

參考文章


https://www.cnblogs.com/shijun/p/3713830.html

https://blog.csdn.net/zfrong/article/details/6183353

https://docs.microsoft.com/zh-cn/previous-versions/dotnet/netframework-3.5/6bs4szyc(v%3dvs.90)

https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2008/yx7xezcf(v=vs.90)


文章和觀點,有可能由於知識和閱歷的緣由,分析片面,請多諒解。

相關文章
相關標籤/搜索