.NET Standard庫引用致使的FileNotFoundException探究

微軟近幾年推出.NET Standard,將.NET Framework,.NET Core,Xamarin等目標平臺的api進行標準化和統一化,極大地方便了類庫編寫人員的工做。簡單的說,類庫編寫人員在發佈庫的時候,只須要基於.NET Standard進行發佈,那麼編寫的程序能夠在各個目標平臺上都能到運行。api

.NET Standard是一種標準,只要符合這個標準的平臺均可以運行基於此標準api構建的程序。工具

感受挺好用的,可是實際上用起來就有一些坑了。好比說這個常見的FileNotFoundException,當有這個狀況的時候,常常出現:測試

主程序的目標平臺是某個具體平臺(不是.NET Standard,好比說是.NET Framework 4.0),隨後爲了引入新的特性,升級了Framework爲4.6.1,它而且引用了一個.NET Standard類庫,剛好,這個類庫還引用了其餘的package。(即傳遞引用A->B->C的形式,其中A是.NET Framework程序,B是nuget包,C是B引用的nuget包。)在此狀況下,若是F5啓動程序,就會報FileNotFoundException。code

測試條件
Visual Studio 2015 Community
測試用包:UnifiedConfig v1.1.6get

提示未找到System.IO.FileSystem。乍看感受是一個簡單的引用錯誤,但unifiedconfig包裏面已經正常引用了這個項目,按道理vs可以正常幫咱們處理引用問題。到文件輸出路徑中查看,發現對應的包沒有正確複製過來。手動從package文件夾中複製過來,問題解決。it

緣由出在這個跨平臺上。因爲存在引用傳遞,B不能肯定須要複製哪一個目標平臺的package到A的輸出路徑。當程序是從舊的Framework升級而來的時候,舊版的項目文件不能很好地處理.NET Standard的這個問題。但咱們手動一個一個複製也不是辦法,如下給出解決方案。io

解決方案:配置

  1. 最直接的方案,修改主項目的.csproj文件,將<RestoreProjectStyle>PackageReference</RestoreProjectStyle>添加到第一個PropertyGroup
  2. 若是還不行,加上<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    或者
  • 在工具->nuget包管理器->程序包管理->默認包管理格式,從Packages.config改爲PackageReference。

後記

我記得在visual studio 2017早期版本還存在這個bug,升級以後visual studio 2017 15.6.4這個版本測試新建項目,已經沒有這個問題。而且默認生成的基於4.5.2以上Framework的.csproj文件已經添加<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>這個配置。可是當老版本的項目引用.NET Standard類庫的時候,仍是常常會出現這個問題,這時候,就須要咱們手動添加配置項目了。引用

相關文章
相關標籤/搜索