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版本的规则如下:

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

(全文完)


微信公众号:老王Plus

扫描二维码,关注个人公众号,可以第一时间得到最新的个人文章和内容推送

本文版权归作者所有,转载请保留此声明和原文链接

Dotnet Core使用特定的SDK&Runtime版本的更多相关文章

  1. dotnet core 出现Can not find runtime target for framework '.NETCoreApp,Version=v1.6' 的解决办法

    如果你在更新dotnet core新的类库后运行程序提示如下的错误: Can not find runtime target for framework '.NETCoreAPP, Version=v ...

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

    作者:陈希章 发表于 2017年12月19日 引子 这一篇文章将用一个完整的实例,给大家介绍如何基于dotnet core(微软.NET的最新版本,支持跨平台,跨设备的应用开发,详情请参考 https ...

  3. devOps开发(Web API 实例)dotnet core 和 Azure PaaS服务

    使用 dotnet core 和 Azure PaaS服务进行devOps开发(Web API 实例) 作者:陈希章 发表于 2017年12月19日 引子 这一篇文章将用一个完整的实例,给大家介绍如何 ...

  4. 【ASP.NET Core分布式项目实战】(五)Docker制作dotnet core控制台程序镜像

    Docker制作dotnet core控制台程序镜像 基于dotnet SDK 新建控制台程序 mkdir /home/console cd /home/console dotnet new cons ...

  5. publish dotnet core angular spa app to docker

    公司一个使用Angular开发的应用准备下个版本使用.Net Core开发后台, 刚好可以用到.Net Core Angular Spa模板, 而且最近也在学习Docker, 于是就想把它融汇贯通, ...

  6. 探索 dotnet core 为何在 Windows7 系统需要补丁的原因

    在一些 Windows 7 系统上,根据 dotnet 官方文档,需要安装上 KB2533623 补丁,才能运行 dotnet core 或 .NET 5 等应用.尽管非所有的设备都需要安装此,但这也 ...

  7. dotnet core 2.1 使用阶梯编译

    在 dotnet core 2.1 可以使用阶梯编译的方法,从 dotnet framework 开始,在代码的所有方法在第一次进入的时候就需要使用 JIT 进行编译为本机的代码.可以看到代码是在第一 ...

  8. dotnet core 使用 PowerShell 脚本

    本文告诉大家如何在 dotnet core 通过 Host PowerShell 的方法使用 PowerShell 脚本 本文提供的方法需要在 dotnet core 2.1 和以上的版本,对于 do ...

  9. Docker 简单发布dotnet core项目 图文版

    原文:https://www.cnblogs.com/chuankang/p/9474591.html docker发布dotnet core简单流程 需要结合这个版本看哈 地址:https://ww ...

随机推荐

  1. 水仙花数的条件:1.是一个三位数,2.个百千位数字的3次方加起来的和等于当前的三位数。如果,想要完美一点可以在外部加while循环

    #!/usr/bin/env python# -*- coding: utf-8 -*-print("请输入三位数:")num = input()# 定义常量SumNum = 0# ...

  2. 2019UNCTF

    Easyshellcode: 不说了,都是没有工具的血泪史,直接上exp: from pwn import * from numbers import * from ae64 import AE64 ...

  3. IDEA编写JavaWeb出现乱码,成功解决!

    使用IDEA写JavaWeb项目时,总会出现编码出错等问题,比如下面这样,页面显示出来一大堆乱码,下面跟着我来操作一下,可以成功解决! 首先在IDEA安装目录下有一个:bin的文件夹,打开后找到如下两 ...

  4. Unity3D获得服务器时间/网络时间/后端时间/ServerTime,适合单机游戏使用

    说明 一些游戏开发者在做单机游戏功能时(例如:每日奖励.签到等),可能会需要获得服务端标准时间,用于游戏功能的逻辑处理. 问题分析 1.自己如果有服务器:自定义一个后端API,客户端按需请求就行了: ...

  5. swift基本数据类型使用

    swift基本数据类型的使用之一: 字符串的使用 swift String的使用 1.字符串的定义 1> 不可变字符串的定义 2> 可变字符串的定义 2.获取字符串的长度 3.字符串的拼接 ...

  6. [LeetCode]Mysql系列5

    题目1 1112. 每位学生的最高成绩 编写一个 SQL 查询,查询每位学生获得的最高成绩和它所对应的科目,若科目成绩并列,取 course_id 最小的一门.查询结果需按 student_id 增序 ...

  7. JVM运行时数据区--程序计数器

    JVM中的程序计数寄存器(Program Counter Register)中,Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息.CPU只有把数据装载到寄存器才能够运行.JVM中 ...

  8. openstack核心组件——glance— 镜像服务(6)

    云计算openstack核心组件——glance— 镜像服务(6)   一.glance介绍:              Glance是Openstack项目中负责镜像管理的模块,其功能包括虚拟机镜像 ...

  9. hystrix总结之缓存

    通过实现HystrixCommand或者HystrixObservableCommand的getCacheKey方法,可以启动缓存. public class CommandUsingRequestC ...

  10. Python爬虫和函数调试

    一:函数调试 用之前学过的try···except进行调试 def gameover(setA,setB): if setA==3 or setB==3: return True else: retu ...