.NET 5: Merging .NET Core and .NET Standard with New Target Framework Monikers (TFMs)

Wait, before we begin, what is a Target Framework Monitor… ahem, sorry, Moniker, not Monitor, I mean, what is a Target Framework Moniker?

When you create a C# project, you’ll get a .csproj file, which is your C# project file. There are two versions of that file available:

  1. Old format: It’s what you get by default with .NET Framework projects
  2. New format (also called SDK-style format): It’s what you get with modern .NET Core projects

You can differentiate between the two very easily. Both formats are XML-based, and both have a Project root element. In an SDK-style .csproj file, that Project element has an Sdk attribute. In the old format, it doesn’t have that Sdk attribute.

So, which format do you see below, old format or new SDK-style format:

<Project ToolsVersion="15.0"

Yes, it’s the old format, no Sdk-attribute on the Project element. And now, here’s the new, SDK-style format. Note the Sdk attribute on the Project element:

<Project Sdk="Microsoft.NET.Sdk">

You can use the new project format not only to target .NET Core or .NET Standard, but also to target .NET Framework and other .NET platforms. So, in this post, let’s forget about the old .csproj format and let’s focus on the modern, SDK-style format.

In the snippet above, you can see a TargetFramework element that specifies the target framework for the project. In the snippet above, the target framework is netstandard2.0. And exactly this name, netstandard2.0, is a so-called Target Framework Moniker (TFM).

So, a TFM is a name that uniquely identifies a target framework.

There are many of these TFMs around. Here three very popular TFMs:

  • net48 targets .NET Framework 4.8
  • netcoreapp3.1 targets .NET Core 3.1
  • netstandard2.1 targets .NET Standard 2.1

A few days ago a huge .NET 5 proposal was pushed to GitHub that shows what will happen with TFMs in .NET 5.0.

First of all, the goal of that proposal is NOT to replace any existing TFM.

But there will be a new TFM that is called net5.0. Note the dotted version number. The TFMs of .NET 5.0 and future .NET versions use a dotted version number!

That means that net48 is like mentioned above the TFM for .NET Framework 4.8. On the other side, net48.0 with the dotted version number targets .NET 48 that will be released in around 43 years in the year 2063. 🙂

Sounds confusing, but I guess it’s the best solution without breaking existing TFMs. And once we’re beyond the .NET 5 phase, we’ll soon forget about the older TFMs like net48net472 etc. So, golden rule is: Use the dotted version number for .NET 5.0 and later, and you’re fine.

.NET Core and .NET Standard are merged into .NET 5.0

The TFM .net5.0 can be used to build a .NET 5.0 class library that can be consumened by any .net5.0 application. This means, today you think about whether you’re building a .NET Standard or a .NET Core class library. You use .NET Standard to re-use your class library on other .NET platforms like Xamarin or Blazor WebAssembly.

But with .NET 5, .NET Core and .NET Standard are merged, and you don’t have to think about whether to use .NET Standard or .NET Core anymore. You just create a .NET 5.0 class library and you can use it with any .NET 5.0 application. The .csproj looks like this:

<Project Sdk="Microsoft.NET.Sdk">

Here a simple view of this:

One can think of net5.0 as .NET Standard but with an implementation (.NET Core).

Immo Landwerth (PM on .NET) on GitHub

But of course, such a .NET 5.0 class library cannot contain any OS-specific code, as it can be used in any .NET 5.0 application. Remember:

.NET 5.0 is a cross-platform framework

What if you want to build a WPF or WinForms project with .NET 5.0? Then you use the OS-specific TFM, in this case net5.0-windowsDotnet9站长注:站长用.net 5 rc2创建wpf应用程序,编译失败在Goolge上找到这篇文章的。).

There are also other OS-specific TFMs available, they are related to today’s Xamarin TFMs:

  • net5.0-android
  • net5.0-ios
  • net5.0-macos
  • net5.0-tvos
  • net5.0-watchos

With these TFMs, you can optionally specify a version after the OS, like for example net5.0-ios13.0.

I think this is a very solid design, and I like it.

Read more about it in this proposal on GitHub.

原文出处: Thomas Claudius Huber