1. 問題描述
A程序集引用了 Newtonsoft.Json 6.0程序集
B程序集引用了 Newtonsoft.Json 10.0程序集
此時A引用B,就會報:發現同一依賴程序集的不同版本間存在無法解決的衝突 這一警告,執行程序就會報錯–System.IO.FileNotFoundException: 未能加載文件或程序集Newtonsoft.Json xx.x的錯誤
A:引用Newtonsoft.Json 6.0
FuncA()
{
var obj= Newtonsoft.Json.Obj;
B.FuncB();
}
B: 引用Newtonsoft.Json 10.0
FuncB()
{
return Newtonsoft.Json.Obj;
}
2. 原因分析
- 這是因爲依賴順序引起的。A引用了B,首先會先生成B,而B引用了 Newtonsoft.Json 10.0,那麼VS就會將源引用文件(Newtonsoft.Json 10.0)複製到B程序集同一目錄(bin/Debug)下,名爲Newtonsoft.Json.dll文件,其內嵌程序集版本爲10.0。
- 然後A引用了B,所以會將B程序集和B程序集的依賴項10.0(Newtonsoft.Json.dll)給複製到A的程序集目錄下,而A又引用了Newtonsoft.Json 6.0程序集文件,所以又將6.0的dll文件給複製到自己程序集目錄下。因爲兩個Newtonsoft.Json.dll重名,所以直接覆蓋了前者,那麼只保留了Newtonsoft.Json 6.0。
- 當我們調用Func方法中的B.FuncB()時候,CLR會搜索B程序集,找到後再調用 return Newtonsoft.Json.Obj 這行代碼,而這行代碼又用到了Newtonsoft.Json程序集,接下來CLR搜索Newtonsoft.Json.dll,文件名稱滿足,接下來CLR判斷其標識,發現版本號是6.0,與B程序集清單裏註冊的10.0版本不符,故而纔會報出異常:未能加載文件或程序集Newtonsoft.Json 10.0。
3 解決方案
- 通過bindingRedirect節點重定向,即當找到10.0的版本時,給定向到6.0版本
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json"
publicKeyToken="30ad4fe6b2a6aeed"
culture="neutral" />
<bindingRedirect oldVersion="10.0.0.0"
newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
- 對每個版本指定codeBase路徑,然後分別放上不同版本的程序集,這樣就可以加載兩個相同的程序集
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json"
publicKeyToken="30ad4fe6b2a6aeed"
culture="neutral" />
<codeBase version="6.0.0.0"
href="E:\6.0\Newtonsoft.Json.dll" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json"
publicKeyToken="30ad4fe6b2a6aeed"
culture="neutral" />
<codeBase version="10.0.0.0"
href="E:\10.0\Newtonsoft.Json.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
END |