dotnet core TargetFramework 解析順序探索

dotnet core TargetFramework 解析順序測試

Intro

如今 dotnet 的 TargetFramework 愈來愈多,拋開 .NET Framework 不談,若是一個類庫支持多個 TargetFramework 應用實際運行的時候會使用哪一個版本的 API 呢,以前一直都是想固然的自覺得是了,因而想測試一下實際解析是怎麼樣的,來看下面的示例吧git

Sample

Library Sample

首先來看類庫示例項目:github

項目文件以下:c#

類庫提供了多個 TargetFramework 的支持:app

  • 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 應用,項目文件示例以下:.net

Console 應用支持的 TargetFramework 以下:code

  • 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:xml

EOL-warning

因此在項目文件中配置了 <NoWarn>;NETSDK1138</NoWarn> 來忽略這個警告blog

測試代碼很簡單,直接調用類庫示例中的測試方法:

Console.WriteLine(Test.GetResult());

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

Test Output

接着咱們就來測試吧,先思考一下吧,不一樣的 TargetFramework 輸出的結果分別是什麼呢?

net6.0

net6.0

net5.0

net5.0

netcoreapp3.1

netcoreapp3.1

netcoreapp3.0

netcoreapp3.0

netcoreapp2.1

netcoreapp2.1

netcoreapp2.0

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

相關文章
相關標籤/搜索