Since the original release of .NET framework in 2002, the .NET ecosystem expanded with many alternative .NET runtimes: .NET Core, Universal Windows Platform (UWP), Xamarin, Unity Game Engine and others.
Although these runtimes are quite similar to each other, there are some differences between their base class libraries (BCL), which makes it difficult to share source code between projects targeting different runtimes.
Microsoft’s first attempt at solving this problem was using portable class libraries (PCL), which allowed building binary compatible assemblies that could be used with multiple runtimes. Portable class libraries required the target runtimes to be selected when creating the library, as based on this choice, the intersection of available APIs was calculated.
Are you keeping up with new developer technologies? Advance your IT career with our Free Developer magazines covering C#, Patterns, .NET Core, MVC, Azure, Angular, React, and more. Subscribe to the DotNetCurry (DNC) Magazine for FREE and download all previous, current and upcoming editions.
With increasing number of runtimes and their different versions, this approach was becoming ever more difficult manage.
Hence, .NET Standard was introduced as an alternative for easier cross-platform development. It takes a reversed approach to determining the available set of APIs. Instead of calculating them based on the targeted runtimes, it specifies them on its own and requires the runtimes to support them.
For existing runtimes, it specifies several different versions with an increasing number of supported APIs.
To learn more about .NET Standard, you can read my previous article on DotNetCurry.com: .NET Standard – Simplifying Cross Platform Development.
.NET Standard 2.0
The biggest obstacle to a larger .NET Standard 1.x adoption was a rather small set of available APIs.
The goal of .NET Standard 2.0 is to remove this obstacle.
In comparison to .NET Standard 1.6, .NET Standard 2.0 includes more than 20,000 additional APIs. These APIs are already a part of .NET framework, but have been missing from .NET Standard before.
.NET Standard - API Scope
Since .NET Standard is focused on cross-platform compatibility, it still doesn’t include all of the .NET framework APIs and it never will.
By design, it excludes all application model APIs, such as WPF, Windows Forms, ASP.NET and others.
It also excludes all Windows specific APIs that were included in .NET framework, e.g. APIs for working with registry and event logs. Most of the .NET framework APIs that do not fall in the above two categories are included in .NET Standard 2.0.
Some of the most notable additions that were missing from .NET Standard 1.6 are:
- System.Data namespace with DataSet, DataTable, DataColumn and other classes for local data manipulation that were commonly used in earlier versions of .NET framework before the release Entity Framework.
- XmlDocument and XPath based XML parsers in addition to XDocument, which was the only one available before .NET Standard 2.0.
- System.Net.Mail, System.Net.WebSockets and other previously missing network related APIs.
- Low level threading APIs such as Thread and ThreadPool.
There’s also one namespace that remains unsupported, but is worth mentioning as it might be a bit surprising: System.Drawing. That’s because it is mostly just a thin layer over the native GDI+ Windows component and therefore can’t be easily ported to other runtimes.
Since it is probably the most commonly used .NET framework API that’s still missing from .NET Standard, the .NET team is currently considering different options on how to make it available elsewhere and include it in .NET Standard. We can expect it to be added at least partially in future versions of .NET Standard.
Of course, it’s impossible to list all the changes here. The best place to check for individual API availability in .NET Standard 2.0 is the official reference documentation.
.NET Standard - Assembly Compatibility
An increased API set in .NET Standard 2.0 will make it much easier to compile existing source code that was originally written for .NET framework, against .NET Standard, and make it available to other runtimes. At least as long as it is not dependent on particular application models.
This means that business logic could be shared across runtimes, but applications will still need to be written for each runtime.
However, our own source code, even with business logic, often depends on other third party libraries, not only on the base class library APIs that are now exposed via .NET Standard.
As expected, .NET Standard libraries can reference other .NET Standard libraries that target the same or lower version. They can also reference compatible portable class libraries.
Unfortunately, a large majority of third party libraries that are currently available on NuGet does not target .NET Standard or PCL, but rather .NET framework. Although many of those could maybe easily just recompiled for .NET Standard with minimal or no code changes at all, this still needs to be done by their authors who might not actively maintain them anymore.
To avoid that requirement altogether, .NET Standard 2.0 includes a special compatibility shim, which makes it possible to reference existing .NET framework libraries from .NET Standard libraries without recompilation.
To allow that, any references to .NET framework classes from the referenced .NET framework library are type forwarded to their counterparts in .NET Standard. Hence, the compiled code will also work in other runtimes, not only in .NET framework.
Image 1: Type forwarding for referenced .NET framework libraries
Of course, this doesn’t mean that any .NET framework library on NuGet will just work with .NET Standard. If it uses any APIs that are missing from .NET standard, the call will fail.
To estimate the severity of this issue, Microsoft did an analysis of all the libraries that are currently available on NuGet and published the results. According to it, over two thirds of libraries in their latest version are API compatible with .NET Standard 2.0, i.e. they either target .NET Standard or PCL, or they target .NET framework but only use APIs that are part of .NET Standard 2.0.
Almost two thirds of those that are incompatible, depend on APIs in specific application models (WPF, ASP.NET, etc.) and are therefore not appropriate for use from .NET Standard.
The rest mostly use APIs that were already considered for .NET Standard but were excluded as too hard to implement across all runtimes. It is therefore not expected that compatibility will significantly increase with future .NET Standard versions.
Image 2: Assembly compatibility in NuGet (source: .NET Standard – NuGet Analysis)
A small number of API compatible libraries from the above analysis (less than 7%) uses P/Invoke to call into native libraries. Although these assemblies can be used from .NET Standard, they will only work on Windows (when referenced from .NET framework or .NET Core applications) but will fail on other operating systems because of their dependencies on native binaries.
During Build 2017, .NET Core 2.0 Preview 1 was released with full support for .NET Standard 2.0. This allows applications written for .NET Core 2.0 Preview 1 to reference .NET Standard 2.0 libraries and API compatible .NET framework libraries and still run on all three currently supported operating systems: Windows, Linux and macOS.
.NET Core 2.0 Preview 1 is freely available for download, but it is not yet ready for production use. However, the SDK is installed side-by-side with the current stable version and you can test it without affecting your work on production projects for .NET Core.
To develop applications for .NET Core 2.0 and .NET Standard 2.0 you can install Visual Studio 2017 Preview 15.3. It also supports side-by-side installation with the stable version of Visual Studio 2017 and will thus not affect your regular .NET development. If you’re not using Windows, you can also develop for .NET Core 2.0 using the latest version of Visual Studio for Mac or Visual Studio Code with its C# extension.
The final version of .NET Core 2.0 and .NET Standard 2.0 is planned for the third quarter of 2017. At that time, full support for .NET Standard 2.0 should also be available in .NET framework and Xamarin.
Universal Windows Platform (UWP) will add support for .NET Standard 2.0 with Windows 10 Fall Creators Update, which is announced for fall 2017. Microsoft is also collaborating with Unity Game Engine developers to add .NET Standard 2.0 support as part of their transition to a newer version of Mono. No information about its availability has been published yet.
As a complement to .NET Standard, XAML Standard was also announced at Build 2017. It is an effort to define standard XAML vocabulary elements for describing user interfaces. The current proposal is being designed publicly on GitHub.
The first version of the standard (XAML Standard 1.0) is planned for release later this year.
After the specification is completed, support is planned to be added to Universal Windows Platform and Xamarin applications. This will allow views to be shared between the applications for these two runtimes. Additional XAML-based application models might add support for XAML Standard in the future.
With version 2.0, .NET Standard is evolving from a promising tool for cross-platform development into an essential part of making .NET Core a more viable and attractive runtime.
The larger set of APIs and the ability to use existing .NET framework libraries will make it much easier to create cross-platform libraries for sharing common business logic between multiple runtimes (e.g. an ASP.NET Core web application, a desktop .NET framework application and a mobile Xamarin application will all share the same assemblies with business logic).
Although the tools are not yet ready for production, they can already be used for testing how well this approach can work for your projects.
XAML Standard is the UI equivalent of .NET Standard. However, it is still in very early stages and it’s therefore difficult to judge how it will turn out. If it is of interest to you, now is the right time to get involved on GitHub and affect its development.
This article was technically reviewed by Suprotim Agarwal.