dotnet core TargetFramework 解析顺序测试

Intro

现在 dotnet 的 TargetFramework 越来越多,抛开 .NET Framework 不谈,如果一个类库支持多个 TargetFramework 应用实际运行的时候会使用哪个版本的 API 呢,之前一直都是想当然的自以为是了,于是想测试一下实际解析是怎么样的,来看下面的示例吧

Sample

Library Sample

首先来看类库示例项目:

项目文件如下:

类库提供了多个 TargetFramework 的支持:

  • netstandard2.0
  • netcoreapp2.1
  • netstandard2.1
  • netcoreapp3.1
  • net5.0
  • net6.0
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp2.1;netstandard2.1;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
</PropertyGroup>
</Project>

类库里只提供了一个类,只有一个用于测试的方法,方法实现如下:

public class Test
{
public static string GetResult()
{
var result = string.Empty; #if NET6_0
result = "NET6.0";
#elif NET5_0
result = "NET5.0";
#elif NETCOREAPP3_1
result = "NETCOREAPP3_1";
#elif NETCOREAPP3_0
result = "NETCOREAPP3_0";
#elif NETCOREAPP2_1
result = "NETCOREAPP2_1";
#elif NETSTANDARD2_1
result = "NETSTANDARD2_1";
#elif NETSTANDARD2_0
result = "NETSTANDARD2_0";
#endif return result;
}
}

通过条件编译在不同的 TargetFramework 下返回不同的值以测试实际执行的代码

Executable Sample

接着看一个可执行的 Console 应用,项目文件示例如下:

Console 应用支持的 TargetFramework 如下:

  • netcoreapp2.0
  • netcoreapp2.1
  • netcoreapp3.0
  • netcoreapp3.1
  • net5.0
  • net6.0
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;netcoreapp2.1;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<NoWarn>;NETSDK1138</NoWarn>
</PropertyGroup> <ItemGroup>
<ProjectReference Include="..\TestClassLibrary\TestClassLibrary.csproj" />
</ItemGroup> </Project>

因为 netcoreapp2.0.netcoreapp3.0 已经不再支持,如果直接使用会得到一个 Warning:

所以在项目文件中配置了 <NoWarn>;NETSDK1138</NoWarn> 来忽略这个警告

测试代码很简单,直接调用类库示例中的测试方法:

Console.WriteLine(Test.GetResult());

Console.WriteLine("Hello World!");
Console.ReadLine();

Test Output

接着我们就来测试吧,先思考一下吧,不同的 TargetFramework 输出的结果分别是什么呢?

net6.0

net5.0

netcoreapp3.1

netcoreapp3.0

netcoreapp2.1

netcoreapp2.0

More

从上面的测试结果其实就能够大概看出来,多个 TargetFramework 的解析顺序,可执行应用程序首先会匹配与当前运行的 TargetFramework 相符的框架,如果没有与当前运行的 TargetFramework 相符的框架,则会fallback 到低版本的 .NET 框架上,优先选择高版本的框架,如果当前运行的框架版本是 net6.0,但是类库不支持 net6.0,则会使用 net5.0,如果类库不支持 net5.0 则会使用 netcoreapp3.1以此类推。

如果既有 .NET Core 的框架支持又有 .NET Standard 的支持,则会优先使用 .NET Core 框架,没有可用的 .NET Core 框架的话再开始看类库支持的 .NET Standard 的支持,优先选择当前框架支持的高版本的 .NET Standard 框架

最后扩展一下,引用单个类库是上面这样的,如果类库引用了类库,那又会如何呢

测试项目结构如下,测试项目基于 .NET6.0,引用了一个基于 netstandard2.0/netstandard2.1 的类库项目 ClassLibrary1,而 ClassLibrary1 引用了另外一个基于netstandard2.0/netstandard2.1/netcoreapp2.1的类库项目,测试方法和上面的差不多,测试项目调用 ClassLibrary1 中的测试方法(实际调用了 ClassLibrary2 中的测试方法)

ConsoleApp(NET6.0)

  • ClassLibrary1(netstandard2.0/netstandard2.1)

    • ClassLibrary2(netstandard2.0/netstandard2.1/netcoreapp2.1)

输出结果如下:

从上面的结果来看,实际的解析结果运行结果都是根据最终执行到的类库结合应用当前运行框架来决定使用哪个版本的代码的

References

dotnet core TargetFramework 解析顺序测试的更多相关文章

  1. dotnet core 发布配置(测试数据库和正式数据库自动切换)

    一.起源 在进行项目开发时,常常要求开发环境,测试环境及正式环境的分离,并且不同环境运行的参数都是不一样的,比如监听地址,数据库连接信息等.当然我们把配置信息保存到一个文件中,每次发布的时候,可以先修 ...

  2. [C#]使用 C# 代码实现拓扑排序 dotNet Core WEB程序使用 Nginx反向代理 C#里面获得应用程序的当前路径 关于Nginx设置端口号,在Asp.net 获取不到的,解决办法 .Net程序员 初学Ubuntu ,配置Nignix 夜深了,写了个JQuery的省市区三级级联效果

    [C#]使用 C# 代码实现拓扑排序   目录 0.参考资料 1.介绍 2.原理 3.实现 4.深度优先搜索实现 回到顶部 0.参考资料 尊重他人的劳动成果,贴上参考的资料地址,本文仅作学习记录之用. ...

  3. dotnet core 开发体验之Routing

    开始 回顾上一篇文章:dotnet core开发体验之开始MVC 里面体验了一把mvc,然后我们知道了aspnet mvc是靠Routing来驱动起来的,所以感觉需要研究一下Routing是什么鬼. ...

  4. dotnet core开发体验之开始MVC

    开始 在上一篇文章:dotnet core多平台开发体验 ,体验了一把dotnet core 之后,现在想对之前做的例子进行改造,想看看加上mvc框架是一种什么样的体验,于是我就要开始诞生今天的这篇文 ...

  5. spring cloud+dotnet core搭建微服务架构:服务发现(二)

    前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...

  6. spring cloud+dotnet core搭建微服务架构:Api网关(三)

    前言 国庆假期,一直没有时间更新. 根据群里面的同学的提问,强烈推荐大家先熟悉下spring cloud.文章下面有纯洁大神的spring cloud系列. 上一章最后说了,因为服务是不对外暴露的,所 ...

  7. spring cloud+dotnet core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

  8. 边缘化搭建 DotNet Core 2.1 自动化构建和部署环境(下)

    写在前面 本篇文章是上一篇边缘化搭建 DotNet Core 2.1 自动化发布和部署(上)的后续操作,本文主要讲解如何开启Docker Remote API,开启Remote API后的权限安全问题 ...

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

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

随机推荐

  1. OutOfMemoryError系列

    OutOfMemoryError系列 1.[OutOfMemoryError系列(1): Java heap space](https://blog.csdn.net/renfufei/article ...

  2. Java 实现Redis客户端,服务端

    Java 实现Redis客户端,服务端 1.Java实现Redis发布订阅 1.1实例 2.[Redis]Java实现redis消息订阅/发布(PubSub) 3.java实现 redis的发布订阅 ...

  3. Shiro权限项目

    目录 环境配置 spring容器 springmvc freemarker mybatis shiro 工具类 TokenManager.java Result.java 功能实现 登录 注册 个人中 ...

  4. Codeforces Round #648 (Div. 2) C. Rotation Matching

    题目链接:https://codeforces.com/contest/1365/problem/C 题意 有两个大小为 $n$ 的排列,可以循环左移或右移任意次,问最多有多少对同一值在同一位置. 题 ...

  5. P3376 【模板】网络最大流——————Q - Marriage Match IV(最短路&最大流)

    第一道题是模板题,下面主要是两种模板,但都用的是Dinic算法(第二个题也是) 第一题: 题意就不需要讲了,直接上代码: vector代码: 1 //invalid types 'int[int]' ...

  6. Linux ulimit使用

    什么是ulimit? ulimit是一个可以设置或者汇报当前用户资源限制的命令.使用ulimit命令需要有管理员权限,它只能在允许使用shell进行控制的系统中使用.也就是说它已经被嵌入到shell当 ...

  7. Ansible主机清单Inventory文件hosts

    Ansible主机清单Inventory文件hosts 发表于 2017-05-14 | 分类于 运维相关 , Ansible | | 阅读次数 4638 | 字数统计 1,442 | 阅读时长预计 ...

  8. 力扣119.杨辉三角II-C语言实现

    题目 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行. 在杨辉三角中,每个数是它左上方和右上方的数的和. 示例: 输入: 3 输出: [1,3,3,1] 来源:力扣(LeetCod ...

  9. 关于rand()

    虽然很早就知道rand是伪随机了,但是一般都懒得用srand. 直到模拟银行家算法时不用srand就造成数据实在有点假(-_-||) 所以要记得srand((int)time(0))啊

  10. 仿射加密与S-DES加密算法的实现

    仿射加密 #include <iostream> #include <cstdio> using namespace std; char letter[30]; char _l ...