.NET 5: Merging .NET Core and .NET Standard with New Target Framework Monikers (TFMs)Thomas Claudius Huber
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:
- Old format: It’s what you get by default with .NET Framework projects
- 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
So, which format do you see below, old format or new SDK-style format:
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> ... </Project>
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 Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> </Project>
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:
net48targets .NET Framework 4.8
netcoreapp3.1targets .NET Core 3.1
netstandard2.1targets .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
net472 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
.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"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> </Project>
Here a simple view of this:
One can think ofImmo Landwerth (PM on .NET) on GitHub
net5.0as .NET Standard but with an implementation (.NET Core).
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
There are also other OS-specific TFMs available, they are related to today’s Xamarin TFMs:
With these TFMs, you can optionally specify a version after the OS, like for example
I think this is a very solid design, and I like it.
Read more about it in this proposal on GitHub.