Dotnet Core的SDK版本總在升級,怎麼使用一個特定的版本呢?
假期過完了,心情還在。今天寫個短的。
一、前言
寫這個是因為昨天刷微軟官方文件,發現global.json
在 SDK 3.0 後,更新了一些內容。文件提到了這個更新,但規則說的不太清楚,所以研究了一下,成了這個文章。
先普及一下 .Net Core Runtime 和 .Net Core SDK 的區別,如果請楚,這段可以直接跳過。
我們用命令
% dotnet --list-sdks
檢視已安裝的Dotnet框架時,會查到類似於下面的內容:
1.1.14 [/usr/local/share/dotnet/sdk]
2.1.600 [/usr/local/share/dotnet/sdk]
2.1.602 [/usr/local/share/dotnet/sdk]
2.1.604 [/usr/local/share/dotnet/sdk]
2.1.700 [/usr/local/share/dotnet/sdk]
2.1.801 [/usr/local/share/dotnet/sdk]
2.2.203 [/usr/local/share/dotnet/sdk]
3.0.100 [/usr/local/share/dotnet/sdk]
3.1.101 [/usr/local/share/dotnet/sdk]
可以看到,我們安裝了兩類的東西,.Net Core SDK 和 .Net Core Runtime,並且各自對應的版本。其實,SDK 和 Runtime 各有各的用處:
- .Net Core Runtime - 執行時框架。顧名思義,就是
.Net Core
應用執行時需要使用的框架/庫。這個框架很小,只能用於執行編譯後的程式碼。也就是說,編譯後的程式執行時,會呼叫這個框架裡的庫。 - .Net Core SDK - 這個框架很大,是用來做除了執行以外的其它部分:編譯、除錯應用,以下管理NuGet包等等。當我們開發時,主要用的是這個框架。
所以,在開發機器上我們就需要安裝 SDK 和 Runtime 兩個框架,而在生產機器上,就僅安裝 Runtime 就好了。
同時,SDK 和 Runtime 是對應的,一個特定版本的 SDK,總會對應一個特定版本的 Runtime。
在微軟的體系中,.Net Core SDK 是向後相容的,SDK 3.1 完全可以用來構建 SDK 2.2 類似的應用程式。換句話說,通常不用指定特定版本的SDK來構建應用,用最高的版本就可以。
但是,因為不同的版本,有不同的支援內容,和不同的特性,所以總有些應用是無法相容的。因此,需要指定特定的 Runtime 版本。
為防止非授權轉發,這兒給出本文的原文連結:https://www.cnblogs.com/tiger-wang/p/13811777.html
二、指定特定的SDK版本
前面說了,因為 SDK 向後相容,通常我們不需要關心安裝了哪個版本的 SDK。
但是,總有一些情況會出現:特定版本的BUG、特性變化、專案模板的改變等,導致專案需要某一特定的 SDK 版本。這個時候,我們會用到global.json
。
應用在執行時,dotnet.exe
會在專案目錄中查詢global.json
檔案,並根據global.json
檔案的內容來決定使用哪個 SDK 版本來執行應用。當global.json
不存在時,就使用當前最新的 SDK 版本。
按照微軟的說法,應用SDK版本的規則如下:
- 安裝了哪個版本的SDK;
- global.json定義使用哪個版本的SDK;
- 當前SDK版本的前滾策略是什麼;
- 是否允許使用預釋出版本;
我們也依照這些因素來說明這個問題。
2.1 檢查已安裝的版本
在本文開頭,給出了一個命令:
% dotnet --list-sdks
這個命令,可以列出已經安裝的所有 SDK 及版本號。
微軟的版本號會有點複雜,這裡舉個例子解釋一下,2.1.602:
- 最前邊的 2,是主版本號;
- 中間的 1,是副版本號;
- 後面的三個數中第一個數是特徵版本號,在本例子中,是6;
- 後面三個數中後兩個數是補丁版本號,在本例中是02,表示第6個特徵版本的第2個補丁。
通常我們在說版本時,一般說到的就是主版本號和副版本號。比方 .Net Core SDK 3.1,就是指主版本為3,副版本為1的版本。
這個版本號,在前滾策略中會很重要。
2.2 global.json
global.json
檔案從 .Net Core 1.0就開始引入了。
早期(.Net Core 3.0之前)的內容很簡單:
{
"sdk": {
"version": "2.1.600"
}
}
在這個版本中,global.json
檔案僅定義了應用使用哪個版本的 SDK。執行時,如果安裝對應版本的 SDK,就會正常使用 SDK 並啟動。如果不存在對應的 SDK,則會報錯:
A compatible installed .NET Core SDK for global.json version [2.1.600] from [.\global.json] was not found
Install the [2.1.600] .NET Core SDK or update [.\global.json] with an installed .NET Core SDK
這個階段的global.json
使用單一版本號,並且不支援萬用字元。
在一定程式上,這個設定可以解決一些版本方面的問題。但也帶來了新的問題。
我們看上面的定義, version
欄位的值定義到了版本號的特徵版本號和補丁版本號。也就是說,它定義了單一的一個精確版本號。這使得我們不能使用同主副版本的其它任何 SDK 版本,哪怕它是一個更好或更新的版本。
這個問題在 .Net Core 3.0 後有了新的改善。
.Net Core 3.0 後,global.json
增加了兩個欄位:rollForward
和allowPrerelease
:
{
"sdk": {
"version": "2.1.600",
"allowPrerelease": true,
"rollForward": "patch"
}
}
在這個設定,有三個引數:
- version : 設定的特定版本。如果沒有設定,將採用安裝的最高版本
- allowPrerelease : 計算使用版本時,是否考慮使用
prerelease
或preview
的SDK版本 - rollForward : 要應用的前滾策略
這是微軟對global.json
引數判斷的流程,供參考。
下面,我們重點說一下前滾策略引數。
2.3 前滾策略引數
前滾策略用於確定在請求給定版本時應該選擇已安裝的 SDK 中的哪一個。通過更改前滾策略,您可以放鬆或收緊選擇條件。這個說法有點抽象,我們舉幾個例子來說。
在 .Net Core 3.0中,前滾策略有三個類,九個值:
禁用策略:
- disable - 禁用前滾。如果沒有確定的版本,就報錯。也就是說,不允許使用除指定的版本外的其它任何版本。
保守策略(比禁用要寬鬆一點):
- patch - 如果版本不存在,就使用相同主、副、特徵版本下的最高版本,沒有就報錯。以上面的例子來說,會使用 2.1.604 版本
- feature - 優先套用 patch 策略;如果不存在,就使用主、次版本相同的下一個特徵版本,如 2.1.7xx,沒有就報錯
- minor - 優先套用 feature 策略;如果不存在,就使用主版本相同的最大版本 2.x.xxx,如本例中的 2.2.203
- major - 優先套用 minor 策略;如果不存在,就使用已安裝的最大版本 x.x.xxx,如本例中的3.1.101
最新策略(最寬鬆的策略):
- latestPatch - 始終使用相同主、副、特徵版本下的最高版本 2.1.6xx
- latestFeature - 始終使用相同主、副版本下的最高版本 2.1.xxx
- latestMinor - 始終使用相同主版本下的最高版本 2.x.xxx
- latestMajor - 始終使用已安裝的最高版本
出於對 .Net Core 3.0 以前的配置進行相容,以前的設定會自動採用 latestMajor 設定。
三、總結
一般來說,應用開發中儘可能不要使用global.json
。因為限定了執行時版本,會讓生產環境變得複雜。
如果必須使用global.json
,以我的經驗,建議指定最低的 SDK 版本,並適當地應用 latestMinor 或 latestFeature 策略。這可能確保專案可以由更多的 SDK 版本進行構建和執行。
(全文完)
微信公眾號:老王Plus 掃描二維碼,關注個人公眾號,可以第一時間得到最新的個人文章和內容推送 本文版權歸作者所有,轉載請保留此宣告和原文連結 |