有时候,我们真想用新框架,可也真不想改代码。

有一个前置的知识需要了解,就是微软 Dotnet Core 框架的版本体系。我前边的文章「Dotnet Core使用特定的SDK&Runtime版本」有详细的说明,可以去翻翻看。

前言

有一个旧应用,是在 Dotnet Core 2.1 下编译的服务端应用。本来跑的很好。最近,服务器上的 Dotnet Core Runtime 框架统一升级到 3.1,于是,这个程序就出问题了。

运行时,会报以下的错误:

% dotnet theapp.dll
It was not possible to find any compatible framework version
The framework 'Microsoft.NETCore.App', version '2.1.0' was not found.- The following frameworks were found:3.1.11 at [/usr/share/dotnet/shared/Microsoft.NETCore.App]You can resolve the problem by installing the specified framework and/or SDK.The specified framework can be found at:- https://aka.ms

为什么会这样?

这个情况,源于微软的默认框架运行规则:Dotnet Core 应用运行时,要求运行时的版本,主版本号与编译程序的SDK版本相同,次版本号等于或高于编译程序的SDK版本。

比方我们上边这个程序,编译 SDK 的版本是 2.1.0,因此默认可以运行在装有 Dotnet Runtime 2.1.0 - 2.1.28 的所有运行时下。 

但是,现实的情况,我们希望升级框架的主版本。要知道,现在 Dotnet 5.0 已经成为常规版本,6.0 也已经到了第五个 Preview 了,升级是必然的。

那么,升级完框架后,如何升级已有的应用?

如何升级已有的应用?

通常会有这么几种方式,来升级已有的应用:

1. 升级应用的编译 SDK 版本

说白了,就是在指定的新的 SDK 版本下,重新编译重新生成。

指定特定的 SDK 版本,只需要打开对应工程的.csproj文件,在里面加入下面的内容:

<PropertyGroup><TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

这里面,我们以指定 Dotnet 3.1 为例子。

这儿要注意,5.0 之前,TargetFramework 对应的名称为 netcoreapp,例如 netcoreapp2.1、netcoreapp3.1,而 5.0 之后,微软把名称改了,变成了 net5.0、net6.0。 

这个方式,算是几种方式中,比较麻烦的一种。最基本的前提是,要有工程的源代码。

如果没有源代码,又该怎么办呢?

2. 显式覆盖运行时

Dotnet 命令行有一个参数,可以显式指定使用特定运行时版本来覆盖编译版本对应的运行时。

这个参数就是 --fx-version。

使用时,命令如下:

% dotnet --fx-version "3.1.11" theapp.dll

还是上面的例子,这样一个命令,就可以让 2.1.0 下编译的应用,在 3.1.11 的运行时下运行。而这个 3.1.11,就是安装的运行时的版本号。 

如果不知道已安装的运行时的准确版本号,可以用以下命令查询:

% dotnet --list-runtimes
Microsoft.AspNetCore.App 3.1.11 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.11 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

3. 显式覆盖 .runtimeconfig.json 文件

这是另一种显式改变运行时的方式。

我们观察项目的编译结果目录,会看到一个跟随应用的 .runtimeconfig.json 文件。以上面的例子来说,会叫做 theapp.runtimeconfig.json。如果没有,可以手工创建一个。

看一下它的内容:

{"runtimeOptions": {"tfm": "netcoreapp2.1","framework": {"name": "Microsoft.NETCore.App","version": "2.1.0"}}
}

在这个配置文件中,微软提供了一个前滚策略,可以通过 rollForward 来定义如果找不到要求的运行时版本,程序应该如果使用其它版本的运行时。

关于 rollForward 的详细说明,在「Dotnet Core使用特定的SDK&Runtime版本」文章中也有详细的说明,这儿就不再赘述了。我们直接看内容本例的修改内容:

{"runtimeOptions": {"tfm": "netcoreapp2.1","framework": {"name": "Microsoft.NETCore.App","version": "2.1.0","rollForward": "major"}}
}

比较前后两个文件,只是在中间加了一行:"rollForward": "major",就让这个程序在高版本的运行时下正常运行了。

重要的问题

嗯,虽然上面写了三种方式跨框架运行,但是,你一定要注意,跨框架运行,不像看上去那么简单。

你可以去骂微软。微软在做 Dotnet 主要版本的升级时,是有破坏性的更改的。也就是说,后面的版本,并不是完全兼容前边的版本的。某些类或方法,在版本升级时,都可能做了新的设计和变更,一些方法会被取消,甚至连所属的软件包,都可能发生变化。

因此,做完上面的工作后,要做仔细全面的测试。一个应用可以工作得很好,不等于每个应用都可以。

额外的内容:SDK 与 Runtime

在 Dotnet Core 体系中,SDK 与 Runtime 是完全分离的。虽然我们每次安装时,SDK 与 Runtime 总是一起安装。

SDK 的版本,仅仅是一个版本号,不同的版本之间,不具有本质的区别。版本号仅仅表示这个 SDK 支持到哪一个版本的内容。因此,我们可以从当前的 SDK 版本构建任何以前的版本,而不仅仅是当前安装的 SDK 版本。

这个话说起来有点绕,举个例子,我的机器上只装了 Dotnet Core 5.0 SDK,我也可以构建 Dotnet Core 2.0 的应用,而不需要非得装 Dotnet Core SDK 2.0。

当我们 SDK 来构建应用时,SDK 会根据构建的版本,来下载适当的引用包。这些包包含构建应用所需要的占位符、元数据和程序集。而编译系统会根据这些引用程序集来编译代码,以生成应用程序。

所以,实际在开发环境中,只需要安装最新版本的 SDK,就可以了。

运行时则不一样。在早期 Dotnet Framework 系列时,框架是向后兼容的,Framework 4.5 的框架完全可以运行 Framework 2.0 的应用程序。但到了 Dotnet Core,就不一样了,它被明确的版本所定义和区别。旧版本编译的程序,在高版本的运行时上,不一定能正常运行。 

所以,如果你装了一堆 SDK 和 Runtime,你其实可以这样清理:SDK 保留最新的版本,Runtime 保留各个主版本中最新的版本。好在,各个版本仅以目录的形式存在,清理起来很简单。

总结

Dotnet Core 跨框架运行是一个很复杂的内容,如果你从头去翻微软的文档,那会很头大。

因此,我这个文章,用尽量简单的方式,给大家入个门。

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

Dotnet Core应用跨框架版本运行相关推荐

  1. 基于DotNet Core的RPC框架(一) DotBPE.RPC快速开始

    0x00 简介 DotBPE.RPC是一款基于dotnet core编写的RPC框架,而它的爸爸DotBPE,目标是实现一个开箱即用的微服务框架,但是它还差点意思,还仅仅在构思和尝试的阶段.但不管怎么 ...

  2. dotnet core 应用是如何跑起来的 通过自己写一个 dotnet host 理解运行过程

    在上一篇博客是使用官方提供的 AppHost 跑起来整个 dotnet 程序.本文告诉大家在 dotnet 程序运行到托管代码之前,所需要的 Native 部分的逻辑.包括如何寻找 dotnet 运行 ...

  3. 国产中标麒麟Linux部署dotnet core 环境并运行项目 (三) 部署运行WEB API项目

    部署dotnet Core Web API 上一步的文章,是我们公司最核心的一个ORM组件,在中标麒麟系统完成了一个插入数据的任务,这一步是将正式的从dot net framework 迁移到 dot ...

  4. 基于.NET CORE微服务框架 -谈谈surging的服务容错降级

    一.前言 对于不久开源的surging受到不少.net同学的青睐,也受到.net core学习小组的关注,邀请加入.NET China Foundation 以方便国内.net core开源项目的推广 ...

  5. dotnet core 微服务教程

    这个教程主要是对于第一次使用dotnet core开发的同学. 运行环境是在centos 7 , 使用了docker容器. 即这是一篇运行在linux的docker容器上的微服务的简单应用. 一. 安 ...

  6. 基于.NET CORE微服务框架 -谈谈surging API网关

    1.前言 对于最近surging更新的API 网关大家也有所关注,也收到了不少反馈提出是否能介绍下Api网关,那么我们将在此篇文章中谈谈surging Api 网关 开源地址:https://gith ...

  7. 基于.NET CORE微服务框架 -谈谈Cache中间件和缓存降级

    1.前言 surging受到不少.net同学的青睐,也提了不少问题,提的最多的是什么时候集成API 网关,在这里回答大家最近已经开始着手研发,应该在1,2个月内会有个初版API网关,其它像Token身 ...

  8. win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序

    本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...

  9. Dotnet Core使用特定的SDKRuntime版本

    Dotnet Core的SDK版本总在升级,怎么使用一个特定的版本呢?   假期过完了,心情还在.今天写个短的. 一.前言 写这个是因为昨天刷微软官方文档,发现global.json在 SDK 3.0 ...

最新文章

  1. AI一分钟 | 小米发布小爱音箱mini,169元;天猫汽车无人贩卖机大楼落地,刷脸可购车试驾
  2. jdbc hibernate ibatis 操作Blob 和Clob类型字段(不断更新)
  3. 国内Python最有钱途的方向,开发第二,它排第一!
  4. 单片机小白学步系列(十二) Proteus仿真软件简介
  5. 【CodeForces - 485C】Bits (二进制相关,数学,贪心)
  6. python数据结构简单总结
  7. CodeIgniter URL添加后缀
  8. 在组织中为IT部门构建小型冠军的最快方法
  9. Jmeter跨线程组调用变量
  10. 新版office365介绍
  11. Hbase与pegasus对比
  12. 幻方矩阵(魔方矩阵)
  13. 软考每日一练||网络工程师
  14. “酷我音乐”借“大数据”名义 恐已窥探并收集用户隐私长达数年
  15. 关于ASP木马提升权限
  16. 大数据面试重点之kafka(七)
  17. EasyNLP玩转文本摘要(新闻标题)生成
  18. 怎么打开华硕电脑计算机功能,华硕笔记本小键盘怎么开(笔记本电脑虚拟键盘怎么打开)...
  19. 寒假总结和新学期计划
  20. 毕业四年的职场经历自述

热门文章

  1. 【转】Android编程点滴(14) -- Android中资源文件夹res/raw和assets的使用
  2. static作用:静态变量的生存周期和作用域
  3. webpack二(以webpack4.x起步)
  4. 纯CSS制作各种各样的网页图标(三角形、暂停按钮、下载箭头、加号等)
  5. 30分钟掌握 C#7
  6. [Java] java中的接口定义
  7. [Usaco2007 Demo][BZOJ1628] City skyline
  8. hdu 1800 (map)
  9. Teams App如何选择用户
  10. Google在Android P中隐藏了真棒的按应用自动旋转功能