After more than two years since the release of .NET Core 2.0 in August 2017, .NET Core 3.0 was released as the next major version of .NET Core. It’s been supported for use in production since July 2019 when Preview 7 of .NET Core 3.0 was released. The next long-term support (LTS) version will be .NET Core 3.1 in November 2019.
To develop for .NET Core 3.0, you need an up-to-date version of Visual Studio 2019. There’s no support for it in Visual Studio 2017.
As a companion to .NET Core 3.0, .NET Standard 2.1 is also being released. In comparison to .NET Standard 2.0, the latest 2.1 includes many new classes and methods which were added to .NET Core 3.0 making it possible for cross-platform class libraries to use them as well.
Despite that, it’s still a good idea to write your libraries for .NET Standard 2.0 whenever possible because this will make them available to different .NET runtimes, e.g. .NET framework which isn’t going to support .NET Standard 2.1 and previous versions of .NET Core. You can read more about .NET Standard in my previous article – .NET Standard 2.0 and XAML Standard.
.NET Core 3.0
.NET Core 3.0 is also the first .NET runtime to fully support C# 8.0. You can read more about the new language features that it introduces in my previous article – New C# 8 Features in Visual Studio 2019.
The so-called .NET Core Global Tools can also be installed as local tools in .NET Core 3.0. Global tools are command line utilities which can be easily installed and run using the dotnet command. They were originally introduced with .NET Core 2.1, but they could only be installed globally (as their name implies) which made them always available from the command line. In .NET Core 3.0, they can also be installed locally as a part of a .NET Core project or solution and as such automatically available to all developers working on the same code repository. You can read more about .NET Core Global Tools in my previous article – .NET Core Global Tools – (What are Global Tools, How to Create and Use them).
Table 1: .NET Core application models and libraries
Windows-Specific Features
Since further development of .NET framework stopped with version 4.8, .NET Core 3.0 has a big focus on Windows-specific features which were previously not supported. The goal is to make .NET Core a way forward for Windows developers who currently use .NET framework. Unlike almost all the other parts of .NET Core so far, these new features will not be cross-platform and will only work on Windows because they heavily rely on services provided by the operating system.
Windows Desktop
The most prominent new feature in .NET Core 3.0 is support for development of Windows desktop applications using Windows Forms or WPF (Windows Presentation Foundation). Both application models are fully compatible with their .NET framework counterparts. Therefore, any existing .NET framework applications using them can be ported to .NET Core unless they depend on some other feature that is not supported in .NET Core, such as .NET Remoting or advanced WCF features for example.
Porting existing .NET framework applications to .NET Core is not trivial and requires some changes to the source code and testing afterwards. Because of this, it only really makes sense for applications which are still being actively developed. Also, the designers in Visual Studio 2019 don’t work yet on .NET Core projects. To use them, a companion .NET framework project is required which shares the files with the .NET Core project. This workaround is required only temporarily, as support for designers will be added to future versions of Visual Studio 2019.
Although Windows Forms and WPF in .NET Core 3.0 are mostly just ports from .NET framework, there are two new features worth mentioning:
- Windows Forms has enhanced support for high DPI screens. Since it is not fully compatible with high DPI behavior in .NET framework, it requires additional testing and potentially changes to source code.
- Both Windows Forms and WPF support XAML islands, i.e. the ability to host UWP (Universal Windows Platform) controls inside a Windows Forms or WPF application). This is particularly useful for (although not limited to) hosting first-party UWP controls such as WebView, Map Control, MediaPlayerElement and InkCanvas).
To simplify deployment of Windows desktop applications developed in .NET Core 3.0, the new application package format MSIX can be used. It’s a successor to previous Windows deployment technologies, such as MSI, APPX and ClickOnce which can be used to publish the applications to Microsoft Store or to distribute them separately. A dedicated Windows Application Packaging Project template in Visual Studio is available to generate the distribution package for your application.
Support for COM Components
The significance of COM (Component Object Model) components has declined with an increased adoption of .NET framework. However, there are still applications which rely on it, e.g. automation in several Microsoft Office products is based on it.
Entity Framework
Entity Framework is Microsoft’s data access library for .NET. As part of .NET Core, a completely new version of Entity Framework was developed from scratch – Entity Framework Core. Although its API feels familiar to anyone who has used the original Entity Framework, it is neither source code compatible nor feature equivalent to it. Any existing code using Entity Framework therefore needs to be rewritten in order to use Entity Framework Core instead.
To make porting of existing Windows applications using Entity Framework to .NET Core easier, .NET Core 3.0 includes a port of the original Entity Framework in addition to a new version of Entity Framework Core.
Entity Framework 6.3 for .NET Core
Entity Framework 6.3 version in .NET Core is primarily meant for porting existing applications. New applications should use Entity Framework Core instead which is still in active development.
The tooling for Entity Framework is currently only supported in Visual Studio 2019 on Windows. The designer support will be added in a later Visual Studio 2019 update. Until then, the models can only be edited from a .NET framework project similar to the approach required for the Windows Forms and WPF designers.
However, the applications developed with Entity Framework 6.3 for .NET Core can run on any platform which makes it suitable for porting not only Windows desktop applications but also web applications, making them cross-platform in the process. Unfortunately, new providers are required for .NET Core. Currently only the SQL Server provider is available. No support for SQL Server spatial types and SQL Server Compact is available or planned.
Entity Framework Core 3.0
A new version of Entity Framework Core is also included with .NET Core 3.0. Among its new features, the most important are the improvements to LINQ which make it more robust and more efficient because larger parts of the queries are now executed on the database server instead of in the client application. As part of this change, client-side evaluation of queries as fallback when server-side query generation fails, was removed. Only the projection from the final Select part of the query might still be executed on the client. This can break existing applications. Therefore, full testing of existing applications is required when upgrading to Entity Framework Core 3.0.
Additionally, Entity Framework Core 3.0 now includes support for Cosmos DB (implemented against its SQL API) and takes advantage of new language features in C# 8.0 (asynchronous streams). As a result, it now targets .NET Standard 2.1 instead of .NET Standard 2.0 and therefore can’t be used with .NET framework or older versions of .NET Core anymore.
ASP.NET Core
ASP.NET Core is probably the most widely used application model in .NET Core as all types of web applications and services are based on it. Like Entity Framework Core, its latest version works only in .NET Core 3.0 and isn’t supported in .NET framework.
To make applications smaller by default and reduce the number of dependencies, several libraries were removed from the basic SDK and must now be added manually when needed:
- Entity Framework Core must now be added to the project as a standalone NuGet package. A different data access library can be used instead.
- Roslyn was used for runtime compilation of views. This is now an optional feature which can be added to a project using the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation NuGet package.
- JSON.NET as the library for serializing and deserializing JSON has been replaced with a built-in JSON library with focus on high performance and minimal memory allocation. JSON.NET can still be installed into the project and used instead.
Endpoint routing which was first introduced in .NET Core 2.2 has been further improved. Its main advantage is better interaction between routing and the middleware. Now, the effective route is determined before the middleware is run. This allows the middleware to inspect the route during its processing. This is especially useful for implementing authorization, CORS configuration and similar cross-cutting functionalities as middleware.
Server-Side Blazor
Probably the most eagerly awaited new feature in ASP.NET Core 3.0 is Blazor. In .NET Core 3.0, only server-side Blazor is production ready (this feature was named Razor Components for a while in early previews of .NET Core).
Blazor makes client-side interactivity in a browser possible without any JavaScript code. If necessary, JavaScript can still be invoked (e.g. to use browser APIs, such as geolocation and notifications). All the other code is written in .NET instead. In server-side Blazor, this code runs on the server and manipulates the markup in the browser using SignalR. For this to work, a constant connection between the browser and the server is required. Offline scenario is not supported.
Figure 1: Blazor server-side execution model
Client-side Blazor is still in preview and will ship at an unannounced time in the future. As the name implies, all the code runs on the client in the browser like in JavaScript-based SPAs (single page applications). The .NET code is compiled to web assembly so that browsers can execute it.
Figure 2: Blazor client-side execution model
You can read more about Blazor in an (old albeit relevant) article by Daniel Jimenez Garcia – Blazor – .NET in the browser.
Worker Service Template
Worker Service is a new project template for an ASP.NET Core application hosting long-running background processes instead of responding to client requests. There are support classes available to integrate such applications better with the hosting operating system:
Support for gRPC
gRPC is a modern high-performance contract-first RPC (remote procedure call) protocol developed by Google and supported in many languages and on many platforms. It uses HTTP/2 for transfer and Protocol Buffers (also known as Protobuf) for strongly-typed binary serialization. This makes it a great alternative to WCF (Windows Communication Foundation) which has only limited support in .NET Core:
While Web API can be used to implement a REST service, gRPC is better suited to remote procedure call scenarios which were the most common use case for WCF services. Its performance benefits are most obvious when many RPC calls and large payloads are required.
Although a gRPC library for C# has been available for a while, .NET Core 3.0 and Visual Studio 2019 now include first-class support with project templates and tooling to make development easier.
Changes in Deployment Model
.NET Core supports two deployment models:
- Framework-dependent deployments require that a compatible version of the .NET Core runtime is installed on the target computer. This allows the deployment package to be smaller because it only needs to contain compiled application code and third-party dependencies. These are all platform independent, therefore a single deployment package can be created for all platforms.
- Self-contained-deployments additionally include the complete .NET Core runtime. This way the target computer doesn’t need to have the .NET Core runtime preinstalled. As a result, the deployment package is much larger and specific to a platform.
Before .NET Core 3.0, only self-contained deployments included an executable. Framework-dependent deployments had to be run with dotnet command line tool. In .NET Core 3.0, framework-dependent deployments can also include an executable for a specific target platform.
Additionally, in .NET Core 3.0, self-contained deployments support assembly trimming. This can be used to make the deployment package smaller by only including the assemblies from the .NET Core runtime which are used by the application. However, dynamically accessed assemblies (through Reflection) can’t be automatically detected which can cause the application to break because of a missing assembly. The project can be manually configured to include such assemblies, but this approach requires the deployment package to be thoroughly tested to make sure that no required assembly is missing.
Both deployment models now also support the creation of single-file executables which include all their dependencies (only third-party dependencies in framework-dependent deployments, also the .NET Core runtime in self-contained deployments). Of course, these executables are always platform specific.
Startup-Time Improvements
In the field of performance, the following features focus on reducing the application startup-time:
- Two-tier JIT (just-in-time) compiler has been available for a while, but with .NET Core 3.0, it is enabled by default although it can still be disabled. To improve startup-time, two-tier JIT performs a faster lower quality compilation first and makes a slower second pass at full quality later when the application is already running.
- Ready-to-run images introduce AOT (ahead-of-time) compilation to .NET Core. Such deployment packages are larger because they include a native binary alongside the regular IL (intermediate language) assemblies which are still needed. Because there’s no need for JIT compilation before startup, the application can start even faster. For now, there’s no cross-targeting support for creating ready-to-run-images, therefore they must be built on their target platform.
Conclusion
A closer look at .NET Core 3.0 makes it clear that .NET Core is maturing.
Since there’s no further development planned for .NET framework, .NET Core is now the most advanced .NET implementation. It’s cross-platform and more performant than .NET framework.
Most of the features from .NET framework are now also included in .NET Core.
For those features which aren’t planned to be supported in .NET Core, there are alternatives available: for Web Forms, there’s Blazor; for WCF and .NET Remoting, there’re Web API and gRPC; for Workflow Foundation, there’s Azure Logic Apps.
Now is the time to start porting the .NET framework projects you’re still actively developing, if you haven’t done so already. This way, you’ll be ready when .NET 5 arrives, as the unified .NET runtime, by the end of 2020.
This article was technically reviewed by Daniel Jimenez Garcia
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Damir Arh has many years of experience with software development and maintenance; from complex enterprise software projects to modern consumer-oriented mobile applications. Although he has worked with a wide spectrum of different languages, his favorite language remains C#. In his drive towards better development processes, he is a proponent of Test-driven development, Continuous Integration, and Continuous Deployment. He shares his knowledge by speaking at local user groups and conferences, blogging, and writing articles. He is an awarded Microsoft MVP for .NET since 2012.