.NET Standard – What It is And How It Applies to .NET Core

Over on the Coding Blocks Slack group, Luke Warren had suggested that I write a post about the .NET Standard. Luckily for him, I’d already been planning on writing one. The original release would have been towards the middle of December 2016, but I decided to bring it forward a few weeks. So without further ado…

What’s an ado, anyway?

A Problem With .NET

The .NET eco system without a unifying class system
Taken from https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

In the above image (click to enlarge), you can see that each of the major platforms within the .NET ecosystem have their own Base Class Libraries (BCLs).

In the image, they’re labelled “Base Class Library”, “Core Library” and “Mono Class Library”

Each of these platforms uses it’s BCL to communicate with the Common Infrastructure’s APIs. This means that any change made to .NET Framework’s BCL (to implement a newly added feature in the Common Infrastructure, for instance) would have to be replicated across to the BCLs for both .NET Core and Xamarin to keep them all synchronised and offer whatever new feature necessitated the change to .NET Framework.

And anyone who has ever had to support more than one platform will tell you that it’s not an easy task

The main issue here is that supporting three separate libraries (in this example, but many more as the .NET ecosystem evolves) is a non-trivial issue. Especially since Microsoft are looking to push .NET to a whole host over other platforms (including more Linux distributions, and even IoT devices).

Not only is supporting three separate BCLs a big task (what with Microsoft adding new things to .NET Core constantly and merging them back to .NET Framework and Xamarin where applicable, and vice versa), but what if someone wants to port .NET to a new Operating System?

Well, they’d have to implement their own BCL and ensure that it communicates with the Common Infrastructure correctly. Which would be yet another BCL for the community to keep in sync.

Hopefully, you’re starting to see why this is a problem.

This had lead to a situation where developers are having to use conditional compilation on their projects in order to ensure that the libraries they are using provide a minimum selection of BCL APIs – selecting different libraries for different target platforms.

And sometimes this is done by the libraries themselves, behind the scenes.

It also means that Portable Class Libraries are no longer that portable, since developers who are creating them cannot guarantee that all of the required BCL APIs were available on the target platform.

If the target platform wasn’t a full install of Windows, that is. Which is the case if you’re targeting mobile development (Xamarin) or a Linux/unix stack (.NET Core)

This is where the .NET Standard comes in.

.NET Standard

The .NET Standard is Microsoft’s attempt at standardising how the cross platform .NET APIs will work across all supported .NET platforms.

Including IoT and RaspberryPi support, which is coming soon (at the time of writing).

To be able to standardise the way that the many .NET platforms communicate with the Common Infrastructure, Microsoft had written a standard for how a common BCL will work

You can read about the .NET Standard at it’s official GitHub repo, here

.NET Standard is defined as an independent reference assembly that is satisfied by all .NET platforms

The goal of the .NET Standard is to replace the situation in the earlier image (all the way at the top of the article), with one similar to the following (click to enlarge):

The .NET eco system with the .NET Standard Library included
The .NET eco system with the .NET Standard Library included (taken from https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/)

As you can see, the goal here is to create a single BCL for all .NET ecosystem platforms to use. This will remove the issues created by having separate BCLs across each platform.

The extremely important thing about the .NET Standard is this quote:

For developers, this means they only have to master one base class library. Libraries targeting .NET Standard will be able to run on all .NET platforms. And platform providers don’t have to guess which APIs they need to offer in order to consume the libraries available on NuGet.

The above quote is taken from https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

.NET Standard Versioning

I’m not going to go into the history of the .NET Framework, but you can read a little about it here if you wish.

That’s a link to a blog post which I wrote for the company I work for.

The .NET Framework has been around since 2002, so the entire thing is quite well documented.

The biggest issue facing the .NET foundation is that there are versions of the .NET Framework and of the Xamarin stack which implement different features of the Common Infrastructure.

Let’s not mention .NET Core just yet.

So, how do you know which version of what is supported? Well, the idea is the different platforms within the .NET ecosystem will be ratified against versions of the .NET Standard as features are added to those platforms.

The following image (again, click to enlarge) shows some of the projects and which versions of the standard they comply with:

.NET Standard Support Table
The .NET Platforms and which version of the .NET Standard they support

This image is correct at the time of writing this blog post.

The arrows indicate that the platform supports a higher version of .NET Standard. For instance, .NET Core 1.0 supports the .NET Standard version 1.6, which is why there are arrows pointing to the right for the lower versions 1.0 – 1.5.

This means that a developer will be able to choose from a range of ecosystem platforms which support the features that their projects require, by checking which version of the .NET Standard those platforms support. Which, in turn, will increase the developer’s choices for target platforms as the .NET Standard evolves.

By the way, here is the documentation for .NET Standard version 2.0: https://github.com/dotnet/standard/blob/master/docs/netstandard-20/README.md

What Does This All Mean?

This means that developers, technical directors, and any other key decision makers can now know which version of the .NET Standard their chosen platform supports. This will allow them to make decisions based on the requirements of their problem domain.

For instance, if .NET Core 1.0 is chosen as the target platform, then any version of the .NET Standard up to and including 1.6 can be used.

However, if .NET Framework 4.6.1 is chosen, then any version of the .NET Standard up to and including 2.0 can be used.

And here is the NuGet package for .NET Standard 1.6, which contains a list of the packages installed at each version of the .NET Standard: https://www.nuget.org/packages/NETStandard.Library

With this being said, it is important to remember what Immo Landwerth had said on a recent episode of the .NET Rocks! podcast:

There is nothing stopping you from running the .NET Framework and .NET Core on the same server. So why not give it a go?

Since both the .NET Framework and .NET Core can exist on the same system in harmony (they are separate platforms, as far as each other are concerned), it is entirely possible to have multiple applications on the same system, but using different .NET platforms.

This is great from a developer’s persepctive. Even if that developer is simply trialing .NET Core, it means that their .NET Framework applications wont be affected.

A Vision For the Future

Microsoft’s plan is for the .NET Standard is to replace PCLs, which should drive greater compatibility between the different supported operating system platforms.

.NET Standard Library can be thought of as the next generation of Portable Class Libraries (PCL). The .NET Standard Library improves on the experience of creating portable libraries by curating a standard BCL and establishing greater uniformity across .NET runtimes as a result. A library that targets the .NET Standard Library is a PCL or a “.NET Standard-based PCL”. Existing PCLs are “profile-based PCLs”.

Taken from https://docs.microsoft.com/en-us/dotnet/articles/standard/library

This means that your solutions will inform the .NET Runtime about which version of the .NET Standard they target. Since the .NET Standard provides a standard library, you will no longer have to worry about features being missing or not implemented by your target platform.

As long as you check which features are available in the targetted NET Standard version.

In .NET Core, this is done by adding the relevant lines to your project.json file.

This is correct at the time of writing, as project.json is being dropped in future versions of .NET Core.

For instance, to target .NET Standard version 1.6 you would add:

{
"dependencies": {
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.6": {}
}
}
view raw project.json hosted with ❤ by GitHub

to your project.json.

The NETStandard.Library is required to create portable libraries across all .NET runtime platforms.

Looking Ahead

All of this means that as the .NET Standard moves forward, more platforms could be added to the .NET Standard. It also means that you will be able to target a given version of the standard and be safe in the knowledge that whether you use .NET Core, .NET Framework or Xamarin, you will have access to the same standard library.

More Information

The following sites are some of the best places to start with learning about the .NET Standard:

Related Posts

A .NET developer specialising in ASP.NET MVC websites and services, with a background in WinForms and Games Development.

When not programming using .NET, he is either learning about .NET Core (and usually building something cross platform with it), speaking Japanese to anyone who’ll listen, learning about languages, writing for his non-dev blog, or writing for a blog about video games (which he runs with his brother)

  • Pingback: .NET Standard – What It is And How It Applies to .NET Core - How to Code .NET()

  • First of all, Props for such a clear explanation, I really appreciate it. I do have a question though. We keep hearing about how .NET Core and .NET Standard Library are so wonderful because they allow for modularity via NuGet packages. However, we are told to include the entire “NETStandard.Library” package as a dependency, not just the libraries the that are needed by the project. I feel that I must be misunderstanding something here, because, to me, this seems like the similar situation as we have with the .NET framework (other than the BCL issues) in that one would be required to have the entire .NET Standard Library present to run any application regardless of the platform. Can you help me understand what the expectation is for using the .NET Standard Library in future projects that are meant to be platform agnostic? Are we expected to package the dependent .NET libraries (I.E. specify the packages needed from the standard library individually as NuGet dependencies), or are we supposed to expect the standard library to be installed on any machine running an application, regardless of the .NET platform targeted?

    • Hi Brandon,

      Thank you for reading my article and taking the time to comment.

      I believe that you have the right idea in mind with both points here:

      > Are we expected to package the dependent .NET libraries (I.E. specify the packages needed from the standard library individually as NuGet dependencies), or are we supposed to expect the standard library to be installed on any machine running an application, regardless of the .NET platform targeted?

      There is an expectation that the target machine (on which the .NET Core application will be hosted), will have the required version of the .NET Core runtime installed. This will be the same as the .NET Framework, except that there are cross platform installers for the .NET Core runtime.

      As with .NET Framework, there is an expectation that the target machine will have the minimum required .NET Core framework installed on the host machines. The difference between .NET Core and .NET Framework here being that there are installers for the .NET Core runtime for many different Operating System platforms. Here is a link to the .NET Core downloaders: https://www.microsoft.com/net/core

      There’s also an expectation that the dependencies will be referenced in a compiled binary’s ‘.deps.json’ file.

      One of the steps in running of a .NET Core application is to restore all dependant packages, which will obviously pull down (from NuGet) the latest build of the targeted libraries.

      This works in a similar way as NodeJs, or NuGet packages in .NET Framework applications that are built in Visual Studio (when opening a solution for the first time, Visual Studio will restore any NuGet packages before building) – the difference being that with .NET Core, the dependencies will be pulled and globally installed on first run.

      This will increase first boot time by a small amount (as long as sufficient bandwidth is available on the compilation machine), but it will ensure that the compiled binary will have everything that it needs in order to run on the .NET Core runtime.

      These packages are downloaded and installed in the .nuget/packages directory on the host machine. This in located in the logged in user’s directory (C:Usersuser1 on Windows, and /home/user1 on Linux and Unix-like operating systems – where ‘user1’ is the logged in user).

      I’ve added a screen shot of a truncated ls of the NuGet/packages folder on my machine to give an illustrative example.

      I hope that this answers your question.

      https://uploads.disquscdn.com/images/6238ee282eaaa912d39ebe26ef899c0118f1785e99b15f62669c783ae82f2d28.jpg

  • Pingback: .NET Standard 2.0:整齐划一的目标 - 莹莹之色()

  • Pingback: 52 Posts in 52 Weeks – Jamie's Blog()

  • Hehe. Love it.

  • Hi Neutrino,

    The image was correct, back in November of 2016 (when I originally wrote this blog post). However a lot has changed in the .NET Standard ecosystem since then, especially with the release of .NET Standard 2.0 which, as you point out .NET Framework 4.6.1 full supports.

    I would recommend taking a look at Immo Landwerth’s videos on .NET Standard (here is a link to his playlist https://www.youtube.com/watch?v=YI4MurjfMn8&list=PLRAdsfhKI4OWx321A_pr-7HhRNk7wOLLY ).