The .NET Core 3.0 Preview 1 hit the streets on December 4th at Connect() 2018 and for some of us, it's the biggest release since 1.0. If you're looking for new features, performance enhancements, and bug fixes for ASP.NET Core, Web API, or Entity Framework Core, let me stop you right there. Yes, 3.0 has all that, but if that's what you're looking for, you can find all that in 2.2, which is already ready for prime-time use.

Find additional: .NET Core articles here

.NET Core 3.0 Preview 1

Think of Preview 1 as .NET Core 2.2 + Desktop. The only things in ASP.NET that are in this preview that aren't in 2.2 are support for Blazor (Web assembly), a bleeding edge preview technology, and support for Entity Framework 6, an old technology supported for compatibility purposes. You should also know that there are some breaking changes in ASP.NET Core between 2.2 and 3.0, so this preview may not be worth your while - yet. So, what makes 3.0 Preview 1 the biggest release since 1.0? Desktop!

Who cares about desktop? Millions of developers still develop and maintain WPF and Windows Forms applications and, until this release, there hasn't been much news about desktop development out of Microsoft in years. According to Microsoft, over two million developers actively work on Windows Forms applications every month. Nearly one million developers actively work on WPF applications each month, and I'm one of them.

Think of Preview 1 as .NET Core 2.2 + Desktop

Although most new applications are built for the Web, I still work on several WPF applications. The fact is, some applications still can't be done well in a browser. In fact, we have a whole team at CODE that specializes in high-performance WPF work and does quite well because they can do some amazing things that can't be achieved with other technologies. We've been taking advantage of .NET Core to write services for our desktop apps for a while now, and the apps themselves have required the full framework, installers, and everything that goes with fat client, native desktop applications.

You might be thinking, as I did when I first heard about desktop apps in Core, that .NET Core is cross-platform, which must mean that the desktop apps will be cross-platform too. Well, no! WPF and WinForms are tightly tied to Windows and would look and feel out of place on Linux or a Mac. Perhaps someday there'll be a Mac UI Core, but today is not that day.

You might also be wondering if Core has cool new features for desktop apps. It doesn't. Or wondering if it's 100% compatible with the full framework versions. It's not - yet. Although it does support just about everything that comes with plain, vanilla desktop development from Microsoft, there are some issues with third-party libraries that build on top of the Microsoft-provided features. Larger apps are where you'll find the most issue, but most small apps will work fine as is.

Why, then, am I so excited about it? Because I still create and maintain desktop applications for certain scenarios. Because it clearly signals that Microsoft believes that the desktop isn't dead. Because it provides a channel for all of the new and exciting desktop features that haven't happened over the last half decade. Because it's now open source ( and and that means we can expect new features, performance improvements, and bug fixes faster than Microsoft could ever deliver on their own. Because performance, even in this initial release, is impressive. Because it supports simplified xcopy installation and side-by-side framework versions as well as support for the new MSIX installer format. Because it's cool and it's fun.

Hands On: Creating a New .NET Core WPF Application

Let's take it for a spin. I'm going to show WPF here, but WinForms is very similar. Install Visual Studio 2019 Preview 1 or later if you don't have it already. .NET desktop development and Desktop development with C++ are the only workloads required for this exercise, but I recommend installing at least the following workloads so you have enough pieces and tools to build compelling demos:

  • .NET desktop development
  • Desktop development with C++
  • Universal Windows Platform development
  • ASP.NET and Web development
  • Azure development
  • Data storage and processing
  • .NET Core cross-platform development

VS 2019 has a nice feature that will prompt you to install any components it finds missing, so if something's required that you don't have installed, VS has you covered, and you won't be left wondering what you need to do.

Next, download and install the .NET Core 3.0 SDK preview for Windows from The default installation path is C:\Program Files\dotnet\sdk\3.0.100-preview-009812 and it includes everything you need to create, build, and run 3.0 apps, including the command line interface (CLI). Once it's installed, test it by opening a command prompt and running the following command: dotnet –version. You should get a response that starts with 3.0.100-preview.

As it's a prerelease, there's quite a bit still missing that will be included in future releases. The first thing you'll notice is that there are no project templates for creating new .NET Core WPF or WnForms apps. In the command window, navigate to the folder where you'd like to create your project and type the following command: dotnet new wpf ?name WpfSample1

Figure       1      : Creating a new WPF project with the .NET Core CLI
Figure 1 : Creating a new WPF project with the .NET Core CLI

Now you can open the project in Visual Studio 2019. You'll notice some rough edges in the tooling, such as xaml.cs files not neatly tucked under the corresponding XAML files. I expect tooling issues like this as well as project templates to be included in future releases; certainly before 3.0 ships.

Figure       2      : The new project, opened in Visual Studio 2019 Preview 1
Figure 2 : The new project, opened in Visual Studio 2019 Preview 1

Go ahead and press F5 to run the app and try it out.

Figure       3      : The default application created by the CLI
Figure 3 : The default application created by the CLI

It's not a fancy app, but you can resize it and everything moves around as you'd expect in a WPF application.

If you open the MainWindow.xaml file for editing, you'll notice two things. First, you'll notice that all of the XML namespaces and classes are exactly the same as they are in WPF applications written for the full framework. Next, you'll notice that there is no designer. Although there's a designer on the way, I'll argue that you shouldn't use it anyway. Just as serious Web developers don't use WYSIWYG designers because the layout is fluid changes based on screen and browser size, using the WPF designer imposes those same limitations on your desktop apps. WPF is capable of so much more than static layouts. Your styling should be kept in resource libraries and out of your XAML the same way HTML developers put styling into separate CSS files.

If you open the .csproj file for editing, you'll notice that it's using the new project file format. That's a nice change from the 98 lines of XML produced for the same single form project using the old format. All of the libraries you'll need are added automatically when the TargetFramework and UseWpf properties are set. You'll also notice that none of your source files are in there. The source files become part of the project simply by existing in the project folder. This is a nice change for many reasons and works much better with modern source control systems like Git.

Figure       4      : The new, uncluttered project file format
Figure 4 : The new, uncluttered project file format

Testing Existing WPF Applications in .NET Core

The folder-based approach to including files in the new project format opens up a nice way to test your existing desktop applications under .NET Core 3. I've tested several existing desktop applications using this simple trick and can compile both versions using a single set of source files. Copy or create a new .csproj file with the contents shown above and give it a slightly different name than the existing full framework .NET project. I like to use the same project name with .Core appended to the end.

Place the file in the same folder as the original .csproj file (thus the need for a different name). Add the new .csproj file to the solution and set it as the startup project for the solution. There are a couple of tricks you'll need to know. First, edit the new .csproj file and add a <GenerateAssemblyInfo> tag with a value of False to the PropertyGroup to prevent it from duplicating the project properties when using source files from a full framework app. If you forget this step, you'll get build errors indicating duplicate attributes. You'll also need to add references to any other assemblies your project requires. In many cases, that's all you need to do. In some cases, you might also need to install the latest version of the Microsoft Windows Compatibility Pack (Microsoft.Windows.Compatibility) NuGet package. This fixes issues if your existing app uses any of the Windows APIs such as the Windows registry or directory services.

Figure       5      : Prevent build errors with existing projects by setting GenerateAssemblyInfo false
Figure 5 : Prevent build errors with existing projects by setting GenerateAssemblyInfo false

Depending on which project file you've selected as the startup project in the solution, you'll run either the full framework version of the app or the .NET Core version. You'll find in the bin\Debug folder that the Core version is compiled to a subfolder named netcoreapp3.0. The full version is in the Debug folder.

Figure       6      : A single set of source files with two project files
Figure 6 : A single set of source files with two project files

You'll see the Dependencies folder in the Core project; the full framework version has a References node. All of the source files in the original project are now shared by the Core project. A change to a file in either project changes the file in both. There's another variation of this approach where the new Core project is created in a different folder and the .csproj file is edited to include source files from another folder in an <ItemGroup> tag. I've had a lot of problems with that approach and found it much easier to put both project files in the same folder.

A change to a file in either project changes the file in both.

What Else is New in 3.0 Preview 1?

I already mentioned Blazor/Web assembly and support for EF 6. Well, .NET Core 3 also supports XAML Islands (packaged UWP components), which can be used in your desktop apps. This allows desktop apps to use newer UWP controls like the Edge browser control instead of the IE 9-based browser control we have now. It can also add better support for things that UWP controls do well, such as touch. There's enhanced support for IOT, allowing you to work directly with pins on IOT hardware. There's enhanced Machine Learning support with better support for ML.NET. ASP.NET Core is now an integral part of .NET Core as are WPF and WinForms, not separate installs. There's C# 8 support as well as .NET Standard 2.1 support. There's nascent support for WCF and .NET Remoting. Although it's not in Preview 1, there's planned support for Cosmos DB in EF Core 3 as well as better support for LINQ. The full roadmap can be found at

In Conclusion

Although there will likely be a lot of new features in ASP.NET Core 3.0 and .NET Core 3.0 by the time a release version hits the streets, in Preview 1, the big story is support for desktop applications. Windows Forms and WPF support is here. The tooling is still rough, but if you're a desktop developer, now's a good time to start looking at .NET Core. Radio silence has been broken and improvements are coming in areas that haven't changed in a decade. Now there's the promise that you and the rest of the community can add your own improvements and bug fixes and issue pull requests that could very well make your contribution part of the product. Desktop is dead. Long live Desktop!