Dotnet Core使用特定的SDK&Runtime版本
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 扫描二维码,关注个人公众号,可以第一时间得到最新的个人文章和内容推送 本文版权归作者所有,转载请保留此声明和原文链接 |
Dotnet Core使用特定的SDK&Runtime版本的更多相关文章
- 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 ...
- 使用 dotnet core 和 Azure PaaS服务进行devOps开发(Web API 实例)
作者:陈希章 发表于 2017年12月19日 引子 这一篇文章将用一个完整的实例,给大家介绍如何基于dotnet core(微软.NET的最新版本,支持跨平台,跨设备的应用开发,详情请参考 https ...
- devOps开发(Web API 实例)dotnet core 和 Azure PaaS服务
使用 dotnet core 和 Azure PaaS服务进行devOps开发(Web API 实例) 作者:陈希章 发表于 2017年12月19日 引子 这一篇文章将用一个完整的实例,给大家介绍如何 ...
- 【ASP.NET Core分布式项目实战】(五)Docker制作dotnet core控制台程序镜像
Docker制作dotnet core控制台程序镜像 基于dotnet SDK 新建控制台程序 mkdir /home/console cd /home/console dotnet new cons ...
- publish dotnet core angular spa app to docker
公司一个使用Angular开发的应用准备下个版本使用.Net Core开发后台, 刚好可以用到.Net Core Angular Spa模板, 而且最近也在学习Docker, 于是就想把它融汇贯通, ...
- 探索 dotnet core 为何在 Windows7 系统需要补丁的原因
在一些 Windows 7 系统上,根据 dotnet 官方文档,需要安装上 KB2533623 补丁,才能运行 dotnet core 或 .NET 5 等应用.尽管非所有的设备都需要安装此,但这也 ...
- dotnet core 2.1 使用阶梯编译
在 dotnet core 2.1 可以使用阶梯编译的方法,从 dotnet framework 开始,在代码的所有方法在第一次进入的时候就需要使用 JIT 进行编译为本机的代码.可以看到代码是在第一 ...
- dotnet core 使用 PowerShell 脚本
本文告诉大家如何在 dotnet core 通过 Host PowerShell 的方法使用 PowerShell 脚本 本文提供的方法需要在 dotnet core 2.1 和以上的版本,对于 do ...
- Docker 简单发布dotnet core项目 图文版
原文:https://www.cnblogs.com/chuankang/p/9474591.html docker发布dotnet core简单流程 需要结合这个版本看哈 地址:https://ww ...
随机推荐
- Kubernetes 服务部署最佳实践(一) ——如何更好地设置 Request 与 Limit
如何为容器配置 Request 与 Limit? 这是一个即常见又棘手的问题,这个根据服务类型,需求与场景的不同而不同,没有固定的答案,这里结合生产经验总结了一些最佳实践,可以作为参考. 所有容器都应 ...
- 在Oracle中十分钟内创建一张千万级别的表
小表不会产生性能问题,大表才会.要练习SQL调优,还非得有大表不可.但数据不会自然产生,没有数据时如何创建一张千万级别的大表呢? 之前,我想用Oracle的批量插入语法去插入数据,此语法如下: INS ...
- TCP三次握手、四次挥手理解及可能问为什么?
三次握手: TCP3次握手连接:浏览器所在的客户机向服务器发出连接请求报文(SYN标志为1),此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态. 服务器接收报文后,同意建立连接, ...
- Python实现加密的RAR文件解压(密码已知)
博主之前在网上找了很多资料,发现rarfile库不能直接调用,需要安装unrar模块,下面将详细介绍整个实现流程. 第一步:安装unrar模块,直接pip install unrar可能会找不到库,需 ...
- python基础:异常捕捉
一.异常 python在程序运行过程中,可能会出现一些错误和异常,导致程序停止运行.我们可以通过捕捉异常,并对异常进行处理,使得程序可以正常运行 异常有很多类型,可以根据类型挨个捕捉.也可统一捕获: ...
- conda和pip重新配置源
conda设置源之后出现了问题,报错condaHTTPError: 之前按照网上的一些教程设置了清华源之后,过了一段时间,今天来装新的库时报了以上错误,特此记录一下. conda 源重新设置 重新去清 ...
- HTML -- 表单元素2
(1)<select>元素(下拉列表) <html> <body> <!-- 表单处理程序在action属性中指定 --> <form actio ...
- 分布式系统监视zabbix讲解七之分布式监控
分布式监控 概述 Zabbix通过Zabbix proxy为IT基础设施提供有效和可用的分布式监控 代理(proxy)可用于代替Zabbix server本地收集数据,然后将数据报告给服务器. Pro ...
- k8s健康检查(七)
默认的健康检查 强大的自愈能力是 Kubernetes 这类容器编排引擎的一个重要特性.自愈的默认实现方式是自动重启发生故障的容器.除此之外,用户还可以利用 Liveness 和 Readiness ...
- nioServerChannel的的状态
转载自https://blog.csdn.net/zxhoo/article/details/17964353 Channel继承层次图分析上面提到的三个状态的时候,会去看Channel继承层次里某些 ...
