Dotnet Core使用特定的SDKRuntime版本

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 版本进行构建和运行。

(全文完)

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring中IOC的理解(通俗易懂版)

文章目录1.IOC提出背景2:IOC的核心概念3:IOC的实现方式4:IOC的入门案例(1):思路分析(2):代码解析5:DI入门案例(1):思路分析(2):代码解析6:DI依赖注入的方式(1):前言(2):Set方式注入(3):构造器注入(4):依赖的自动装配7:注解开发模式的依赖注入(1):前言介绍(2):注解模式的依赖注入…

首个使用Blazor 技术实现的社区软件 BlazorCommunity 发布

BlazorCommunity 是首个使用Blazor 实现的开源社区软件, 其组件基于Element-Blazor , Element-Blazor 是一个 API 模仿 Element,CSS 直接使用 Element 样式,HTML 结构直接使用 Element HTML 结构 的 Web开发库。由于基于了…

leetcode112. 路径总和

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

全球顶级开源大神们现身 COSCon'20

点击上方“开源社”关注我们| 作者:Will Wang| 编辑:沈于蓝| 责编:王皓月业界最具影响力的开源年度盛会2020中国开源年会 (COSCon20) 将于 10月24-25日由开源社举办。COSCon 以其独特定位及日益增加的影响力,吸引越来越多的顶级企…

做.NET开发多年,公司要我转Java...

10月13日,.NET5发布了(Release Candidate)RC2版本,包含语言新版本C#9和F#5等,这是正式版前的最后更新!终于,万众期待的.NET5真的要来了!公司让我转Java,我成功说服老板!机会永远留给…

ASP.NET Core Blazor WebAssembly 之 .NET JavaScript互调

Blazor WebAssembly可以在浏览器上跑C#代码,但是很多时候显然还是需要跟JavaScript打交道。比如操作dom,当然跟angular、vue一样不提倡直接操作dom;比如浏览器的后退导航。反之JavaScript也有可能需要调用C#代码来实现一些功能,毕…

leetcode654. 最大二叉树

一:上码 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

浅议C#客户端和服务端通信的几种方法:Rest和GRPC和其他

本文来自:https://michaelscodingspot.com/rest-vs-grpc-for-asp-net/浅议C#客户端和服务端通信的几种方法:Rest和GRPC在C#客户端和C#服务器之间进行通信的方法有很多。一些功能强大,而其他功能则不是很多。有些非常快…

leetcode106. 从中序与后序遍历序列构造二叉树(java详解版)

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

COSCon’20开源教育论坛介绍

点击上方“开源社”关注我们| 作者:周添一| 编辑:沈于蓝| 设计:冯艺怡| 责编:王皓月论坛简介在当今数据驱动的智能社会,软件作为数字智能社会的数据基础设施,承载了社会的高效运转。在这个软件定义世界的潮…

leetcode105. 从前序与中序遍历序列构造二叉树

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

想进BAT等大厂,到底要怎么做?

职场&认知洞察 丨 作者 / findyi这是findyi公众号的第82篇原创文章最近我的公众号多了很多学生读者,很多人问我:如果要进BAT等大厂,我是应该直接工作还是考研?对于未来要从事程序员行业的朋友来说,要不要考研&…

.NET 5.0 RC 2 发布,正式版将在 11 月 .NET Conf 大会上发布

原文:http://dwz.win/ThX作者:Richard翻译:精致码农-王亮说明:1. 本译文舍弃了少许我实在不知道如何翻译但又不是很重要的语句。2. 本文有不少超链接,由于微信公众号和头条平台外链会被剔除 URL 地址,所以原…

leetcode216. 组合总和 III

一:题目 二:上码 class Solution {/**递归深度根据k值确定,宽度的话那就[1,9]因为递归不允许重复&#xff0c;那么的话我们需要每次在横向遍历的起始位置1*/private List<List<Integer>> ans new ArrayList<>();private List<Integer> path new Arr…

BeetleX之Websocket协议分析详解

Websocket应用协议已经普及多年了&#xff0c;它是HTTP1.1的内部升级协议&#xff0c;主要作用是补充HTTP1.1无法灵活地主动推送消息给客户端的缺陷问题。在这里主要介绍一下使用组件如何扩展一个完整的Websocket协议。协议介绍Websocket并不复杂&#xff0c;但协议文档内容还是…

甲骨文是否可以要求 Java API 享有版权?这场10年官司怎么结

美国最高法院10月7日就 Oracle 甲骨文诉 Google 谷歌一案进行口头辩论。案件一直以来争议的核心是&#xff0c;甲骨文是否可以要求 Java API 享有版权&#xff0c;如果可以&#xff0c;那么谷歌是否侵犯了这些版权&#xff1f;Java API 是否可以享有版权&#xff1f;Sun 公司在…

C#知多少 | 每个版本都更新了什么?

总所周知&#xff0c;.NET5.0马上就要来了&#xff0c;最后一个预览版RC2也已经发布了&#xff0c;在11月的时候&#xff0c;我们就正式的发布了&#xff0c;然后我们就可以迁移使用了&#xff0c;当然今天说的重点不是.NET&#xff0c;今天说的是伴随着.NET5一起到来的C#9.0&a…

leetcode40. 组合总和 II(树层去重)

一:题目 二:上码 class Solution {/**注意这里的去重:1.我们分为树层去重比如[1,1 2,5] target 8,那么如果我们用树枝去重的话,那么就会出现[1,2,5],[1,2,5]那么的话我们就需要树层去重 就是横向遇见相同的元素跳过。2.树枝去重的 树枝去重就是 我们数组前面使用过的元素不…

WPF开源控件扩展库 - MaterialDesignExtensions

WPF开源控件扩展库 - MaterialDesignExtensionsMaterialDesignExtensions仓库截图logoMaterial Design Extensions 在WPF开源控件库 ????Material Design in XAML Toolkit(本站介绍&#xff1a;????链接)的基础上进行了控件扩展和特性新增。本开源项目中的控件或许不在…

leetcode131. 分割回文串

一:题目 二:上码 class Solution {/**思路:1.纵向递归的话 我们递归深度是 我们的 切割线切到了最后 2.横向for 我们的宽度就是字符串宽度3.在哪截取的话 那就是在哪个坐标的后面*/List<List<String>> ans new ArrayList<>();List<String> path n…