【Winform】-認識並解決共用專案的Nuget套件陷阱

 當工作與需求多了起來後,勢必就會將一些邏輯與處理整理成共用邏輯庫,然而若共用庫的專案框架是.Net Framework的話,那就會Nuget套件的引用陷阱。本文將介紹並處理這個狀況(不妥協,確實處理)。

簡述

 其實狀況概述就是Winform共用庫的Nuget路徑為相對路徑導致,當共用庫與主專案(起始專案)的結構不同時,就會炸掉。若以熟知該狀況(已被坑)。可以直接跳到解決方法。

狀況介紹

 今天有兩個專案,一個是主要的專案【ComplexPathWinform】與共用庫【DotNetFramworkService】,其中主專案引用共用庫。共用庫加入了兩個套件,一個是大家熟知的Newtonsoft.Json,另一個是不知道哪裡來的隨便套件。

 

 然而當甚麼都還沒幹,也還沒開始寫髒髒的CODE,只是準備建置主專案看看引用參考,就發現炸掉了!明明nuget有正確的將套件拉到方案引用中!?

 原來,仔細看一下共用共用庫的套件使用路徑,哪裡怪怪的?這壓根不是指向"方案"阿,而是原本的專案。因此將專案的.csproj檔打開來看之後就會發現其設定問題....

    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="nunit.framework, Version=3.11.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
      <HintPath>..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll</HintPath>
    </Reference>

 因此整理一下狀況問題就很清楚了,由於共用庫的套件引用預設是相對路徑,因此解決方案的路徑如果結構與共用庫的路徑結構不同,套件就會出錯。這個狀況尤其會發生在導入版本控制的環境,當方案重新下載第一次建置時,就會出現這個問題。(因為共用庫自己原始的方案沒有建置過,nuget還沒拉)

 

問題解決

 一句話,【套件引用位置從"方案"位置開始抓】,問題就解決了。那就來說明作法。做法就是.....,針對共用庫的nuget引用套件,調整<HintPath>路徑。

 【將"..\"改成" $(SolutionDir)\ "】這樣就解決了。(記住是"所有的")

    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>$(SolutionDir)\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="nunit.framework, Version=3.11.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
      <HintPath>$(SolutionDir)\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll</HintPath>
    </Reference>

除了套件引用路徑之外,其他Condition約束也要記得修改

<Import Project="..\packages\NUnit.3.11.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" />

調整為下面
<Import Project="$(SolutionDir)\packages\NUnit.3.11.0\build\NUnit.props" Condition="Exists('$(SolutionDir)\packages\NUnit.3.11.0\build\NUnit.props')" />

調整完後存檔,VisualStudio就會提示專案重新載入,然後問題就解決了。

延伸閱讀

MSDN : Common macros for MSBuild commands and properties ( https://docs.microsoft.com/en-us/cpp/build/reference/common-macros-for-build-commands-and-properties?view=vs-2019 )

備註

1.若共用庫為.Net Core ,沒有這問題。

2.若共用庫為.Net Standard ,也沒有這問題....。

3.為何不要換專案架構?也許是因為Entity Framwork還沒有支援 .Net Standard(.Net Core於2018年就有支援了喔)

4.專案檔.csproj要用甚麼編輯比較有效率?我自己是用Notepad++一次全部取代。

5.延伸閱讀中MSDN連結的最後一個參數,vs-2019代表的就是2019版(時間過真快,抖)。如果想查前面版本的Visual Studio,就改那個參數就可以了(如 vs-2017 / vs-2015)