背景介紹
nuget是.net平臺有效的包管理工具,相信每個C#開發者對它都不陌生。
本文我們來探究一下nuget對不再使用的dll檔案的處理策略,分為如下2個場景:
-
場景A:包A1.0原來包含Newtonsoft.Json.dll,後來更新到包A2.0時不再包含此dll。現在專案中升級包A到2.0,nuget會如何處理Newtonsoft.Json.dll檔案?
-
場景B:包A1.0和包B1.0都包含Newtonsoft.Json.dll,並在專案中同時安裝了這2個包。現在解除安裝包B,nuget會如何處理Newtonsoft.Json.dll檔案?
下面結合現有專案,驗證上述場景看看:
場景A驗證
說明:xxx.MQ就代表包A;xxx.MQ.2.0.36.6版本包含Newtonsoft.Json.dll,xxx.MQ.2.0.36.7版本不包含Newtonsoft.Json.dll;
執行nuget包升級操作後的變化對比如下:
根據上圖驗證效果,可以看到nuget從csproj檔案中移除了Newtonsoft.Json.dll。這種情況其實是符合預期的,因為對dll檔案確實是不再引用了。然而,如果考慮到其它包包含Newtonsoft.Json.dll時,nuget會怎麼處理呢?看下圖:
經過上圖驗證,可以看到nuget還是把Newtonsoft.Json.dll移除了。雖然它是通過xxx.3rd包安裝引入的,那也不行。
場景B驗證
說明:xxx.3rd就代表包A,xxx.MAC代表包B;
執行解除安裝包B操作後的效果如下:
可見解除安裝包B時,直接把Newtonsoft.Json.dll檔案從csproj專案檔案中移除,也是忽略了包A對Newtonsoft.Json.dll的依賴。
上述場景造成的直接影響就是:程式碼中依賴的Newtonsoft.Json的地方,nuget操作後編譯不通過了。當然臨時的解決辦法可以reinstall所需的包,但你不覺得這樣的操作不是那麼優雅麼?
總結
由上述探究可見,nuget包管理工具對dll檔案的管理雖然提供了方便,但是在某些場景下還是會發生不符合預期的情況。如果恰好開發人員再排查不嚴格,那麼甚至會造成dll版本錯亂,進而引發更嚴重的問題。
我們回過頭思考下以上問題的根源是什麼?答案是最小單位的設計!這種模式下的nuget直接操作管理csproj中dll檔案的具體路徑。
如果我們把nuget包整體作為最小單位來維護管理呢?那麼生成專案時,編譯器就約定的路徑下以nuget包為單位定位dll檔案,由於避免了瑣碎的dll檔案路徑管理,因此就壓根不存在dll混亂的問題。
具體如何操作呢?請看微軟推出的nuget升級版:PackageReference!
-
專案檔案中的包引用:https://docs.microsoft.com/zh-cn/nuget/consume-packages/package-references-in-project-files
-
從 packages.config 遷移到 PackageReference:https://docs.microsoft.com/zh-cn/nuget/consume-packages/migrate-packages-config-to-package-reference