NuGet 特有的管理機制

.NET Core SDK 提供了 dotnet restore 指令,但官網的說明很簡單,只說明了他是 restore dependency,到底什麼是 restore dependency 呢 ?

Version


macOS High Sierra 10.13.3
.NET Core SDK 2.1.101
Node.js 8.9.4
NPM 5.7.1

NuGet vs. NPM


NuGet 與 NPM 都是為了解決 package dependency 的問題

相同之處 :

  • NuGet : 採用 csproj 紀錄所使用 package
  • NPM : 使用 package.json 紀錄所使用 package

相異之處 :

  • NuGet : 將 package 統一放在 ~/.nuget/packages,若該 package 有多個版本,則以版本當目錄
  • NPM : 多專案共用的 global package 統一放在 /usr/local/lib/node_modules/npm/node_modules,但若專案自己用的 package 則放在專案目錄的 node_modules

PHP Composer 哲學與 NPM 類似,也分成 global package 與 local package

NuGet 優點

  • 整個系統只有一份 package,省硬碟空間,而不像 NPM 每個專案都有重複的 package。

NuGet 缺點

  • 當你刪除專案,系統可能會留著沒用到的 package
  • 必須要有一份 mapping 檔案,讓 compiler 在 build 時,知道 package 放在哪裡,因為 package 不是放在專案目錄下。

第 2 點就是 dotnet restore 要解決的。

觀察 Console App


estore00

  1. 當使用 dotnet new console 時,事實上只是建立了 csproj
  2. 自動執行 dotnet restore,根據 csproj 建立了 nuget.g.propsnuget.g.targets

estore00

  1. 觀察 nuget.g.props,雖然很多資訊看不懂,但最少看到 <NuGetPackageRoot> 記載著 NuGet 目錄放在 /Users/oomusou/.nuget/packages,這樣 compiler 就可以從這個目錄抓到 NuGet package 放哪裡

之所以沒用 VS Code 開啟專案,是因為 VS Code 還會自動建立其他目錄與檔案,怕模糊焦點,所以這裡選擇 Sublime Text

刪除 obj 目錄


estore00

  1. 選擇 obj 目錄
  2. 刪除 obj 目錄

dotnet restore


1
~/MyProject $ dotnet restore

使用 dotnet restore 重新建立 obj 目錄。

estore00

  1. 輸入 dotnet restore
  2. 根據 csproj 重新建立 nuget.g.propsnuget.g.targets

estore00

  1. obj 目錄被 restore 回來了

.NET Core 2.0


在 .NET Core 1.x 時代,還常常需要自己下 dotnet restore,但從 .NET Core 2.0 開始,當你使用以下 command 時,都會自動執行 dotnet restore

  • dotnet new
  • dotnet build
  • dotnet run
  • dotnet test
  • dotnet publish
  • dotnet pack

所以在實務上已經幾乎不用自己下 dotnet restore 了,只要有觀念即可,為了相容,目前 .NET Core SDK 還是有留下 dotnet restore 指令。

Conclusion


  • dotnet restore 是根據 csproj 建立 package 與實際位置的 mapping 檔案
  • .NET Core 2 之後幾乎不用再自己下 dotnet restore 指令,只要有觀念即可
2018-03-16