Dotnet Core使用特定的SDK&Runtime版本

Dotnet Core使用特定的SDK&Runtime版本

原创 老王Plus的老王 老王Plus 2020-10-14

收录于话题

#Dotnet Core 技术专题

54个

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 版本。

二、指定特定的SDK版本

前面说了,因为 SDK 向后兼容,通常我们不需要关心安装了哪个版本的 SDK。

但是,总有一些情况会出现:特定版本的BUG、特性变化、项目模板的改变等,导致项目需要某一特定的 SDK 版本。这个时候,我们会用到global.json

应用在执行时,dotnet.exe会在项目目录中查找global.json文件,并根据global.json文件的内容来决定使用哪个 SDK 版本来运行应用。当global.json不存在时,就使用当前最新的 SDK 版本。

按照微软的说法,应用SDK版本的规则如下:

  1. 安装了哪个版本的SDK;

  2. global.json定义使用哪个版本的SDK;

  3. 当前SDK版本的前滚策略是什么;

  4. 是否允许使用预发布版本;

我们也依照这些因素来说明这个问题。

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 foundInstall 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增加了两个字段:rollForwardallowPrerelease

{  "sdk": {    "version": "2.1.600",    "allowPrerelease": true,    "rollForward": "patch"  }}

在这个设置,有三个参数:

  • version : 设置的特定版本。如果没有设置,将采用安装的最高版本

  • allowPrerelease :计算使用版本时,是否考虑使用 prereleasepreview的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 版本进行构建和运行。

(全文完)

(0)

相关推荐

  • WPF dotnet core 的 Blend SDK Behaviors 库

    之前版本是通过安装 Blend SDK 支持 Behaviors 库的,但是这个方法都是通过引用 dll 的方式,不够优雅.在升级到 dotnet core 3.0 的时候就需要使用 WPF 官方团队 ...

  • 【翻译】.NET 5 Preview8发布

    今天,.NET 5预览8发布了,对于.NET5.0的功能开发已经完成了,这必须要排除待处理的bug,预览8是最后一次预览版本.预计11月正式的.NET5.0版本发布之前还将发布两个正式之前的候选版本, ...

  • 一文说通Dotnet Core的中间件

    前几天,公众号后台有朋友在问Core的中间件,所以专门抽时间整理了这样一篇文章. 一.前言 中间件(Middleware)最初是一个机械上的概念,说的是两个不同的运动结构中间的连接件.后来这个概念延伸 ...

  • 利用VS code 远程调试 docker 中的 dotnet 应用

    前言 最近.Net 5 正式版发布,我也来蹭一点热度. 如题所示,我这次要讲的是debug docker中的dotnet应用.其实之前我已经写过类似主题的随笔,有兴趣回顾的朋友可以看看: VS cod ...

  • 快速搞懂.NET 5/.NET Core应用程序的发布部署

    背景 .NET Framework时代,.NET 应用程序大多直接部署运行在Windows服务器上.无论部署exe,还是IIS站点.或是Windows Service,编译后的程序直接copy.简单配 ...

  • VSC 创建 Net Core 3.0 版本 WebAPI

    首先确保安装好了VSC(这个算是废话......), 并且为VSC安装了Microsoft提供的C#插件, 以及.Net Core 3.0, 然后就可以开始了 1. 使用VSC打开已经创建好的文件夹( ...

  • 【翻译】.NET 5 Preview 1 发布

    去年年底,我们发布了.NET Core 3.0和3.1.这些版本添加了桌面应用程序模型Windows Forms(WinForms)和WPF,ASP.NET Blazor用于构建SPA应用程序和用于构 ...

  • .NET 6 预览版 7 发布

    我们很高兴地发布了 .NET 6 预览版 7.这是我们进入(两个)候选发布版(RC)之前的最后一个预览版.在我们放慢发布速度之前,团队一直在萤窗雪案,以完成最后一组功能.在这个版本中,你将看到各功能的 ...

  • 详解babel8.X版本用法填坑

    话说在前端这一块有一件让人非常匪夷所思的事情,就是包括webpack,包括几乎所有常用的前端模块(包),只要有大版本的更新,必然跟之前的版本大变脸,连api都给你变了,于是出现各种坑,真不知道为什么要 ...

  • 【翻译】.NET 5 Preview2发布

    在4月2日,发布了.NET 5.0 Preview2,这次发布对一些功能和性能做了相关的改进,同时后面也会实施5.0版本更多的功能,其中一些功能设计目前也在dotnet/designs中显示,在.NE ...

  • 打造跨平台.NET Core后台服务

    续之前讲的在TopShelf上部署ASP.NET Core程序,作为后台服务运行,自从.NET Core 3.0出现以后,出现了自带的Generic Host,使得自托管服务变为可能.这种方式和Top ...