Connect(); Special Issue 2018

Volume 33 Number 13

[.NET Core]

What's Coming in .NET Core 3.0

By Scott Hunter; Special Issue 2018

This article discusses technologies that are in preview. All information is subject to change.

.NET Core 3.0 is the next major version of the .NET Core platform. This article walks through the history of .NET Core and demonstrates how it has grown from basic support for Web and data workloads in version 1 to being able to run Web, desktop, machine learning, containers, IoT and more in version 3.0.

.NET Core 1

The .NET Core journey began a few years ago, with version 1 in 2016, with the goal of building the first version of .NET that was open source and cross-platform (Windows, macOS and Linux). This was driven by customers who could only use frameworks that were open source and by other customers who needed their .NET applications to run on Linux servers. Because .NET Core is cross-platform, it was designed so everything could be done from the command line, without the need for an IDE. And learning from the compatibility challenges of one globally installed .NET Framework, it was designed with side-by-side support, including shipping the framework as part of the application so the application doesn’t depend on any framework being installed on the machine. Version 1 shipped with new versions of ASP.NET and Entity Framework (EF) and primarily targeted Web applications.

.NET Core 2

While version 1 got .NET running on new platforms, it supported only a limited set of .NET APIs. In order to address this, we created .NET Standard, which specified the APIs that any .NET runtime must implement so that code and binaries can be shared across .NET platforms and versions. With .NET Standard 2.0, we added more than 20,000 APIs to the .NET Standard spec. Version 2 of .NET Core shipped in June 2017 and included support for .NET Standard 2.0, giving it access to those APIs. We also introduced the Windows Compatibility Pack, which is a NuGet package that includes many Windows-only APIs, such as System.Drawing, System.DirectoryServices and more. ASP.NET Core 2.0 brought Razor Pages and SignalR, two frameworks that were missing from .NET Core 1.0. Entity Framework Core added support for lazy loading, a popular feature from Entity Framework. .NET Core 2 also continued the push to make .NET one of the fastest full-stack frameworks. The TechEmpower benchmark, which is run by an independent company, lists .NET Core as No. 7 in raw plaintext performance and No. 6 in the Fortunes test of Web and data performance, beating Java servlet and Node.js (bit.ly/2PEE1l1).

.NET Core 3.0

.NET Core 3.0 is the next major version of the .NET Core platform. It includes many exciting new features, such as support for Windows desktop applications with Windows Forms (WinForms), Windows Presentation Foundation (WPF) and Entity Framework 6. For Web development it adds support for building client-side Web applications with C# using Razor Components (formerly known as Blazor). And it includes support for C# 8.0 and .NET Standard 2.1.

We are adding support for Internet-of-Things (IoT) scenarios with .NET Core 3.0. You’ll now be able to program hardware pins (for controlling devices and reading sensor data) on the Raspberry Pi and similar devices, and communicate via serial port on all supported OSes (for example, with a Raspberry Pi or Arduino). We’re also adding IoT device support for ARM64 in this release, to complement the ARM32 capability that’s already in place.

.NET Core 3.0 will also fully support ML.NET, our open source machine learning framework built for .NET developers. ML.NET powers products like Azure Machine Learning, Windows Defender and PowerPoint Design Ideas. Using ML.NET you can add many popular machine learning scenarios to your apps like sentiment analysis, recommendations, forecasting, image classification and more. Learn more at bit.ly/2OLRGRQ.

We recently released the first preview of .NET Core 3.0. For more information about .NET Core 3.0 and to try out the preview, see aka.ms/netcore3preview1.

Desktop (WinForms and WPF) and Open Source

WinForms and WPF are two of the most popular .NET application types and are used by millions of developers. .NET Core 3.0 adds support for WinForms and WPF, bringing Windows desktop development to .NET Core. .NET Core has always been about open source, and both frameworks will be open source in GitHub with the rest of .NET Core. For the first time ever, customers will be able to see the open development of these frameworks and can even help by filing issues, fixing bugs or helping develop new features live in GitHub. WinUI XAML Library will also be open sourced, and with XAML Islands you’ll be able to use these controls in WinForms and WPF applications.

Many of the existing WinForms and WPF applications use Entity Framework to access data, so Entity Framework 6 will also be supported on .NET Core.

You might wonder why you’d want to build desktop applications on .NET Core. That’s easy: It will give you access to all the advancements in .NET Core. You can build applications on the latest version of the framework without having to install .NET Core, and you can publish both your application and .NET Core into a single .EXE. .NET Core was designed with side-by-side in mind, so you can have multiple versions on a computer and applications can be locked to the version for which they were designed. And because of this side-by-side nature, the APIs in .NET Core, including WinForms and WPF, can be improved without the risk of breaking applications.

ASP.NET Core 3

.NET Core 3.0 is not all about the desktop, however. There are lots of exciting new features designed for the Web, as well. Let’s take a look at a few of the features on which we’re working.

A common question from customers is how to have an RPC (as in .NET Remoting and Windows Communication Foundation) experience on .NET Core. We are contributing to the gRPC (grpc.io) project to ensure gRPC will have first-class support for .NET developers.

Earlier this year we started an experiment in client-side Web development using .NET that we call Blazor. Blazor enables you to write Web UI components that run directly in the browser on a WebAssembly-based .NET runtime without writing a single line of JavaScript. You author components using Razor syntax, which are then compiled along with your code into normal .NET assemblies. The assemblies and the WebAssembly-based .NET runtime are then downloaded into the browser and executed using only open Web standards (no plug-ins or code transpilation required), as shown in Figure 1.

Client-Side Web Development with Blazor
Figure 1 Client-Side Web Development with Blazor

Alternatively, the same components can be run on the server using .NET Core, where all UI interactions and DOM updates are handled over a SignalR connection, as shown in Figure 2. When the components execute, they track what updates are required to the DOM and send these updates to the browser over the SignalR connection to be applied. UI events are sent to the server using the same connection. This model has several advantages: The download size is much smaller, your code is centralized on the server, and you get all the features and performance benefits of running on .NET Core.

Running UI Web Components on the Server Using SignalR
Figure 2 Running UI Web Components on the Server Using SignalR

For .NET Core 3.0 we’re integrating the Blazor component model into ASP.NET Core. We call this integrated component model Razor Components. Razor Components enable a new era of composable UIs with ASP.NET Core, and full-stack Web development with .NET. Initially for .NET Core 3.0, Razor Components will run on the server, either as standalone routable components or used from Razor Pages and Views. The same components, however, can also be run client side on WebAssembly. In parallel with the .NET Core 3.0 work, we’ll continue work on supporting Razor Components on WebAssembly using the interpreter-based .NET runtime, which we expect to ship in a subsequent release. Later, we also plan to release support for full ahead-of-time compilation of .NET code to WebAssembly, which will bring significant improvements to runtime performance.

EF Core 3.0

LINQ is a beloved .NET feature that enables you to write database queries without leaving your language of choice, taking advantage of rich type information to get IntelliSense and compile-time type checking. But LINQ also enables you to write a virtually unlimited number of complicated queries, and that has always been a huge challenge for LINQ providers. EF Core solves this in part by choosing what parts of a query can be translated to SQL, and then executing the rest of the query in memory. In some situations, this can be desirable, but in many other cases it can result in very inefficient queries that aren’t identified until an application is in production.

In EF Core 3.0 we’re planning to make deep changes to how our LINQ implementation works and how we test it, in order to make it more robust (for example, to avoid breaking queries in patch releases); to enable it to translate more expressions correctly into SQL; to have it generate efficient queries in more cases; and to prevent very inefficient queries from going undetected until production.

We’ve been working on a Cosmos DB provider for EF Core, to enable developers familiar with the EF programing model to easily target Azure Cosmos DB as an application database. The goal is to make some of the advantages of Cosmos DB—like global distribution, “always on” availability, elastic scalability and low latency—even more accessible to .NET developers. The provider will enable most EF Core features, like automatic change tracking, LINQ and value conversions, against the SQL API in Cosmos DB.

Other features we intend to include in EF Core 3.0 are property bag entities (entities that store data in indexed properties instead of regular properties); the ability to reverse-engineer database views into query types; and integration with new C# 8.0 features like IAsyncEnumerable<T> support and nullable reference types.

We understand that porting to EF Core can require a significant effort for many existing applications using previous versions of EF. For that reason, we’re also porting EF 6 to work on .NET Core.

.NET Standard 2.1

When you adhere to the .NET Standard you can create libraries that work on all implementations of .NET, not only .NET Core but also Xamarin and Unity. In .NET Standard 1.x, we modeled only APIs that were already common across the various implementations. With .NET Standard 2.0, we focused on making it easier to port existing .NET Framework code to .NET Core, which resulted in not only an additional 20,000 APIs, but also compatibility mode, which enables you to reference .NET Framework libraries from .NET Standard-based libraries without having to recompile them. For both versions of the standard, there were almost no new components as all the APIs were existing .NET APIs.

With .NET Standard 2.1, this has changed: We’ve added about 3,000 APIs that are mostly brand-new and were introduced as part of the open source development of .NET Core. By adding them to the standard, we’re bringing them to all implementations of .NET Standard.

Among these new APIs are:

  • Span<T> In .NET Core 2.1 we added Span<T>, which is an array-like type that allows representing managed and unmanaged memory in a uniform way and supports slicing without copying. Span<T> is at the heart of most performance-related improvements in .NET Core 2.1. Because it allows managing buffers in a more efficient way, it can help in reducing allocations and copying. If you want to learn more about this type, be sure to read Stephen Toub’s excellent article on Span<T> (msdn.com/magazine/mt814808).
  • ValueTask and ValueTask<T> In .NET Core 2.1, the most significant feature involved improvements in our fundamentals to support high-performance scenarios (bit.ly/2HfIXob), which also included making async/await more efficient. ValueTask<T> already exists and allows you to return results if the operation completed synchronously without having to allocate a new Task<T>. With .NET Core 2.1, we’ve improved this further, making it useful to have a corresponding non-generic ValueTask that allows reducing allocations even for cases where the operation has to be completed asynchronously, a feature that types like Socket and NetworkStream now utilize.
  • General Goodness Since .NET Core was open sourced, we’ve added many small features across the base class libraries, such as System.HashCode for combining hash codes or new overloads on System.String. There are about 800 new members in .NET Core and virtually all of them got added in .NET Standard 2.1.

For more details, check out the .NET Standard 2.1 announcement at bit.ly/2RCW2fX.

C# 8.0

C# 8.0 is the next version of C# and it improves the language in several major ways. Nullable reference types help prevent null reference exceptions and promote null-safe coding practices. You can opt in to the feature to get warnings when you assign null into variables or parameters of, for example, type string. If you want null, you have to say so by using a “string?” nullable reference type.

Async streams do for asynchronous streams of data what async/await did for single asynchronous results. A new framework type IAsyncEnumerable<T> is the async version of IEnumerable<T>, and can likewise be foreach’ed over and yield return’ed:

public static async IAsyncEnumerable<T> FilterAsync<T>(
  this IAsyncEnumerable<T> source,
  Func<T, Task<bool>> predicate)
{
  await foreach (T element in source)
  {
    if (await predicate(element)) yield return element;
  }
}

Among other features, default interface member implementations enable interfaces to add new members without breaking existing implementers. Switch expressions allow more concise pattern matching, and patterns can be recursive, digging deeper into tested values. For more details on C# 8.0 see aka.ms/csharp8.

How Will .NET Framework and .NET Core Move Forward?

.NET Framework is the implementation of .NET that’s installed on more than 1 billion machines and thus needs to remain as compatible as possible. Because of this, it moves at a slower pace than .NET Core. Even security and bug fixes can cause breaks in applications because applications depend on the previous behavior. We’ll make sure that .NET Framework always supports the latest networking protocols, security standards and Windows features.

.NET Core is the open source, cross-platform, and fast-moving version of .NET. Because of its side-by-side nature it can take changes that we can’t risk applying back to .NET Framework. This means that .NET Core will get new APIs and language features over time that .NET Framework can’t.

If you have existing .NET Framework applications, you shouldn’t feel pressured to move to .NET Core if you don’t need to take advantage of any of .NET Core’s features. Both .NET Framework and .NET Core will be fully supported; .NET Framework will always be a part of Windows. Even inside of Microsoft we have many large product lines that are based on .NET Framework and will remain on .NET Framework. But moving forward, .NET Core and .NET Framework will contain somewhat different features.

Wrapping Up

.NET Core 3.0 is scheduled to release in the second half of 2019. It will have open source versions of WinForms and WPF for Windows desktop development. Entity Framework 6 will be included, as well. And ASP.NET Core, Entity Framework Core, .NET Standard and C# will all receive significant updates. This version of .NET Core should seriously be considered for new .NET applications. For more information, see aka.ms/netcore3preview1.

We’re excited about the future of .NET and adding more workloads to .NET Core. I encourage you to try the preview of .NET Core 3.0 and send us feedback.


Scott Hunter works for Microsoft as the director of Program Management for .NET overseeing the runtime, frameworks, managed languages (C#, F#, VB.NET) and .NET tooling. Before this Hunter was the CTO of several startups including Mustang Software and Starbase, where he focused on a variety of technologies—but programming the Web has always been his real passion.

Thanks to the following Microsoft technical experts for reviewing this article: Ankit Asthana, Damian Edwards, Richard Lander, Immo Landwerth, Beth Massi, Mads Torgersen


Discuss this article in the MSDN Magazine forum