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 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增加了两个字段: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 版本进行构建和运行。

(全文完)

喜欢就来个三连,让更多人因你而受益

Dotnet Core使用特定的SDKRuntime版本相关推荐

  1. Dotnet Core应用跨框架版本运行

    有时候,我们真想用新框架,可也真不想改代码.   有一个前置的知识需要了解,就是微软 Dotnet Core 框架的版本体系.我前边的文章「Dotnet Core使用特定的SDK&Runtim ...

  2. 使用 dotnet core 和 Azure PaaS服务进行devOps开发(Web API 实例)

    引子 这一篇文章将用一个完整的实例,给大家介绍如何基于dotnet core(微软.NET的最新版本,支持跨平台,跨设备的应用开发,详情请参考 https://www.microsoft.com/ne ...

  3. [SSCore] 开源dotnet core 版本 SuperSocket

    前言碎语 最近一直在做旧版本dotnet 程序迁移至dotnet core的工作, 非常欣慰dotnet社区的蓬勃发展, 目前大部分的第三方类库或开源代码都有了dotnet core版本 或者可以方便 ...

  4. 温故知新,DotNet Core SDK和.Net CLI十八般武艺

    简介 .NET命令行接口 (CLI) 工具是用于开发.生成.运行和发布.NET应用程序的跨平台工具链. https://docs.microsoft.com/zh-cn/dotnet/core/too ...

  5. MongoDB via Dotnet Core数据映射详解

    用好数据映射,MongoDB via Dotnet Core开发变会成一件超级快乐的事.   一.前言 MongoDB这几年已经成为NoSQL的头部数据库. 由于MongoDB free schema ...

  6. dotnet core 和 dotnet Framework 启动可执行文件的差别

    在 Windows 下,使用 .NET Framework 构建出来的应用,可以只有一个可执行文件,在可执行文件里面包含了 IL 代码.使用 .NET Core 构建出来的应用,将会包含一个 Exe ...

  7. dotnet core高吞吐Http api服务组件FastHttpApi

    简介 是dotNet core下基于Beetlex实现的一个高度精简化和高吞吐的HTTP API服务开源组件,它并没有完全实现HTTP SERVER的所有功能,而是只实现了在APP和WEB中提供数据服 ...

  8. centos 6.5 安装dotnet core 2.2

    .net core 官网地址 https://dotnet.microsoft.com/download 本次安装版本为.net core SDK v2.2.101 1.查看系统版本, 升级系统基本l ...

  9. k8s pod部署到不同node_部署Dotnet Core应用到Kubernetes(一) - 老王Plus

    最近闲了点,写个大活:部署Dotnet应用到K8s. 写在前边的话 一直想完成这个主题.但这个主题实在太大了,各种拖延症的小宇宙不时爆发一下,结果就拖到了现在. 这个主题,会是一个系列.在这个系列中, ...

最新文章

  1. 我的GitHub 欢迎光临
  2. 记一次程序员在办公室里的“撕逼”经历
  3. Spring框架学习笔记11:基于Java配置方式SSM框架西蒙购物网
  4. 【clickhouse】如何处理ClickHouse超时问题
  5. PHP中的预定义常量、预定义变量、魔术常量
  6. leach算法的实现过程_LEACH-REC算法的研究及实现
  7. 最好用的屏幕录像软件,三步实现高清录制?
  8. React 18 超全升级指南
  9. html用css美化表格
  10. DirectX11--HR宏关于dxerr库的替代方案
  11. DNS(域名系统)是什么?
  12. 模拟二进制交叉(SBX)
  13. Windows 2000驱动程序的设计
  14. 谷歌浏览器网页翻译修复BAT脚本
  15. 操作系统实验四:C++实现独占设备的分配与回收算法模拟
  16. 图像处理之图像的几何变换
  17. vuex基础语法、state代码示例、mutations代码示例
  18. 【数据结构】两栈共享空间的进一步理解
  19. win7画面撕裂问题
  20. 任务一:基于控制台的购书系统 java实验报告

热门文章

  1. php OpenSSL 加解密
  2. 网络相关配置,SSH服务,bash, 元字符
  3. [Forward] 因为火炬,所以迟到,工资照扣
  4. 计算机答辩答不上来怎么回答,答辩答不上来怎么办
  5. vista任务栏透明_增加Windows Vista任务栏预览大小的赏金(付费!)
  6. 如何计算iPhone和Apple Watch上的步数
  7. 阿里云一键建站产品,阿里云自营建站-中小企业建站首选
  8. 闭包--闭包作用之保护(一)
  9. 将不确定变为确定~老赵写的CodeTimer是代码性能测试的利器
  10. iOS - block变量捕获原理