Building Cross-Platform Applications with .NET Core


Write once, run anywhere” seems to be the mantra that finds favour with application developers nowadays. This reduces the need for developers to write a lot of redundant code. .NET Core, an open source offering from Microsoft, (yes, Microsoft!) is just the tool for writing code for a cross-platform application that will work on Windows, Linux and macOS systems.

.NET Core is a free and open source framework for developing cross-platform applications targeting Windows, Linux and macOS. It is capable of running applications on devices, the cloud and the IoT. It supports four cross-platform scenarios: ASP.NET Core Web apps, command line apps, libraries and Web APIs. The recently released .NET Core 3 (preview bits) supports Windows rendering forms like WinForms, WPF and UWP, but only on Windows.

Historically, the .NET Framework has worked only on the Windows platform. It was released in 2002, and has millions of applications developed using it, which run on Windows servers and desktops. The stable version of the .NET Framework (Windows only) release is 4.7.2. With the help of the Mono project, developers were able to bring the .NET code on to mobile devices, macOS, and Linux, but not the applications. So they were managing two separate applications for cross-platform compatibility. Now, with the help of .NET Core, they can target any platform without any code changes; in short, they can now “write once, and run anywhere.”

.NET Core is an open source development platform and Microsoft contributed it to the .NET Foundation in 2014. It is now one of the most active .NET Foundation projects. It can be freely adopted by individuals and companies for personal, academic or commercial purposes. Multiple companies use .NET Core as a part of apps, tools, new platforms and hosting services. Some of these companies make significant contributions to .NET Core on GitHub, and provide guidance on product direction as part of the .NET Foundation Technical Steering Group. This group of companies includes Microsoft, Google, Red Hat, Unity, Samsung and JetBrains.

With .NET Core, developers can build and run .NET code on more than one platform of choice. As of this November, .NET Core 2.1 is generally available (production ready) whereas .NET Core 3.0 is under development, having had a few preview releases. .NET 3.0 GA is expected by early 2019.

Table 1: The .NET Core release table

Why should developers care about .NET Core?

Until 2010, every organisation wanted to design its applications using the SOA (service oriented architecture) pattern with API interfaces. The server operating system was chosen first and then the client components. But once the server platform is confirmed, it’s hard to switch between the platforms. Java is well positioned and has become a natural choice for creating cross-platform apps, with Node, Python, etc, now added to this list.

Key things to consider about .NET Core

1. Cross-platform: It runs on Windows, macOS and Linux operating systems. With .NET Core you can target any application type that’s running on any platform. Developers can reuse skills and code across all of them in a familiar environment. From mobile applications running on iOS, Android and Windows, to enterprise server applications running on Windows Server and Linux, or high scale microservices running in the cloud, .NET Core provides a solution for you.

2. Consistent across architectures: It runs your code with the same behaviour on multiple architectures, including x64, x86 and ARM.

3. Flexible deployment: .NET Core can be included in your app or installed side-by-side, user-wide or machine-wide. It can be used with Docker containers, which typically run Linux today, and it can host ASP.NET Core applications, allowing them to take advantage of the benefits of containers and microservices.

4. Modular: .NET Core supports the use of NuGet packages. Instead of assemblies, now developers can work with NuGet packages. In the .NET Framework, the framework updates are typically serviced through Windows updates, but .NET Core relies on its package manager to receive updates.

5. Microservices architecture: A microservices architecture allows a mix of technologies across a service boundary. This technology mix enables a gradual embrace of .NET Core for new microservices that work with other microservices or services. For example, you can mix microservices or services developed with the .NET Framework, Java, Ruby, or other monolithic technologies.

There are many infrastructure platforms available. Azure Service Fabric, for instance, is designed for large and complex microservice systems. Azure App Service is a good choice for stateless microservices. Other alternatives based on Docker fit any kind of microservices approach, as explained in the section on ‘Containers’. All these platforms support .NET Core and make them ideal for hosting your microservices.

6. Open source: .NET Core is open source and uses the MIT and Apache 2 licences. It is part of the .NET Foundation, which is an independent non-profit supporting the innovative, commercial yet open source-friendly .NET ecosystem. Over 25,000 developers from over 1700 companies outside Microsoft are currently contributing to the .NET open source code base. The .NET community is growing fast, and already has a good number of community projects and libraries available for free. In addition to the community and Microsoft, the Technical Steering Group members like Google, JetBrains, Red Hat, Samsung and Unity are guiding the future of the .NET platform.

7. Tools and productivity: The Visual Studio product family provides a great .NET development experience on Windows, Linux, and macOS. The Visual Studio Marketplace has thousands of editor extensions from Microsoft and others. If you prefer to use a different editor, there are .NET command line tools and plugins for many popular editors. .NET helps you develop high quality applications faster. Modern language constructs like generics, Language Integrated Query (LINQ), and asynchronous programming make developers productive. Combined with the extensive class libraries, common APIs, multi-language support and the powerful tooling provided by the Visual Studio family, .NET is the most productive platform for developers.

8. Command line tools: These include easy-to-use command line tools for local development and in continuous-integration scenarios.

9. Performance: .NET Core is fast. Yes, faster than Node.js and Go. Really fast! That means applications provide better response times and require less compute power. Stackoverflow serves 5.3 million page views a day on just nine servers. The popular TechEmpower benchmark compares Web application frameworks with tasks like JSON serialisation, database access, and server-side template rendering, and .NET Core performs faster than any other popular framework.

Microsoft recommends running .NET Core with ASP.NET Core for the best performance and scale. This becomes important when hundreds of microservices are used, in which case fewer servers and virtual machines are needed. The efficiency and scalability gained can translate to a better user experience in addition to cost savings. runs on .NET Core 2.1 and the platform has seen a 34 per cent improvement in its performance, which means fewer machines are required. New Zealand headquartered Raygun has reported that it increased its throughput 2000 per cent by switching from Node.js to .NET Core.

10. Trusted and secure: .NET Core provides you with immediate security benefits through its managed run time. A collection of services prevents critical issues like bad pointer manipulation or malicious attempts to alter compiled code. Microsoft takes security very seriously and releases updates quickly when threats are discovered.

11. A vast ecosystem: You can leverage the vast .NET ecosystem by incorporating libraries from the NuGet package manager, the extensive partner network, and the Visual Studio Marketplace. You can also find answers to technical challenges from the community, MVPs, and large support network.

12. Support: .NET Core is supported by Microsoft, on Windows, macOS and Linux. It is updated for security and quality several times a year. .NET Core binary distributions are built and tested on Microsoft-maintained servers in Azure and supported just like any Microsoft product. Red Hat supports .NET Core on Red Hat Enterprise Linux (RHEL). It builds .NET Core from source and makes it available in the Red Hat Software Collections. Red Hat and Microsoft collaborate to ensure that .NET Core works well on RHEL.

Comparisons with Mono

Mono is the original cross-platform and open source .NET implementation, and it was first shipped in 2004. It can be thought of as a community clone of the .NET Framework. The Mono project team relied on the open .NET standards (notably ECMA 335) published by Microsoft to provide a compatible implementation.

The major differences between .NET Core and Mono include the following.

  • App-models: Mono supports a subset of the .NET Framework app-models (for example, Windows Forms) and some additional ones (like Xamarin.iOS) through the Xamarin product. .NET Core doesn’t support these.
  • APIs: Mono supports a large subset of the .NET Framework APIs, using the same assembly names and factoring.
  • Platforms: Mono supports many platforms and CPUs.
  • Open source: Mono and .NET Core both use the MIT licence and are .NET Foundation projects.
  • Focus: The primary focus of Mono in recent years has been mobile platforms, while .NET Core is focused on the cloud and desktop workloads.
  • Mobile: Xamarin/Mono is a .NET implementation for running apps on all the major mobile operating systems.


C#, Visual Basic and F# languages can be used to write applications and libraries for .NET Core. These languages are or can be integrated into your favourite text editors and IDEs, including Visual Studio, Visual Studio Code, Sublime Text and Vim. This integration is provided, in part, by the good folks from the OmniSharp and Ionide projects.

Comparing .NET Core with .NET Framework

There are fundamental differences between the two and your choice depends on what you want to accomplish. Table 2 guides you on when to use each.

Table 2: A comparison of .NET Core and .NET Framework

Creating a ‘Hello World’ application using .NET Core

Let us look at how to create our first Hello World application using .NET Core in Ubuntu. You can either use the Visual Studio code editor or the command line to write this code. For the sake of simplicity, I am using the command line here.

The prerequisites are:

  • .NET Core SDK 2.1
  • A text editor or code editor of your choice

I am assuming here that you have Ubuntu 18 for this hands-on tutorial. If you have something else, then please go to to get OS-specific SDK installation instructions.

Step 1: Register Microsoft key and feed: Before installing .NET, we’ll need to register the Microsoft key and the product repository, and install the required dependencies. This only needs to be done once, per machine. Open a command prompt and run the following commands:

$ wget -q

$ sudo dpkg -i packages-microsoft-prod.deb

Step 2: Install .NET SDK: Update the products available for installation, then install the .NET SDK. In your command prompt, run the following commands:

$ sudo apt-get install apt-transport-https

$ sudo apt-get update

$ sudo apt-get install dotnet-sdk-2.1

Step 3: Hello, console app! Open a terminal window and create a folder named Hello. Navigate to the folder we’ve created and type the following command:

$ dotnet new console

$ dotnet run

Let’s do a quick walkthrough of these commands. The first command is:

$ dotnet new console

dotnet new creates an up-to-date Hello.csproj project file with the dependencies necessary to build a console app. It also creates Program.cs, a basic file containing the entry point for the application.


<Project Sdk=”Microsoft.NET.Sdk”>






The project file specifies everything that’s needed to restore dependencies and build the program. The OutputType tag specifies that we’re building an executable — in other words, a console application. The TargetFramework tag specifies what .NET implementation we’re targeting. In an advanced scenario, we can specify multiple target frameworks and build to all those in a single operation. In this tutorial, we’ll stick to building only for .NET Core 1.0.


using System;

namespace Hello


class Program


static void Main(string[] args)


Console.WriteLine(“Hello World from DotNET Core Apps in Linux !”);




Note: Starting with .NET Core 2.0, we don’t have to run ‘dotnet restore’ because it’s run implicitly by all commands that require a restore to occur, such as ‘dotnet new’, ‘dotnet build’ and ‘dotnet run’. It’s still a valid command in certain scenarios in which doing an explicit restore makes sense, such as continuous integration builds in Azure DevOps Services or in build systems that need to explicitly control the time at which the restore occurs.

dotnet new calls dotnet restore implicitly. dotnet restore calls into NuGet (.NET package manager) to restore the tree of dependencies. NuGet analyses the Hello.csproj file, downloads the dependencies defined in the file (or grabs them from a cache on your machine) and writes the obj/project.assets.json file, which is necessary to compile and run the sample.

Important: If you’re using a .NET Core 1.x version of the SDK, you’ll have to call dotnet restore yourself after calling dotnet new.

The second command is:

$ dotnet run

dotnet run calls dotnet build to ensure that the build targets have been built, and then calls dotnet <assembly.dll> to run the target application.

$ dotnet run

Hello World from DotNET Core Apps in Linux!!

Alternatively, you can also execute dotnet build to compile the code without running the build console applications. This results in a compiled application as a DLL file that can be run with dotnet bin\Debug\netcoreapp2.1\Hello.dll on Windows (use / for non-Windows systems). You may also specify arguments to the application as you’ll see later on.

$ dotnet bin\Debug\netcoreapp2.1\Hello.dll

Hello World!

As an advanced scenario, it’s possible to build the application as a self-contained set of platform-specific files that can be deployed and run to a machine that doesn’t necessarily have .NET Core installed.

Analyse your .NET apps for portability to .NET Core

Want to make your libraries multi-platform? Want to see how much work is required to make your application compatible with other .NET implementations and profiles, including .NET Core, .NET Standard, UWP, and Xamarin for iOS, Android and Mac? The .NET Portability Analyser is a tool that provides you with a detailed report on how flexible your program is across .NET implementations by analysing assemblies. The Portability Analyser is offered as a Visual Studio Extension and as a console app. You can get more details about it at

In my next article, we will look at how to create a ASP.NET Core 2.1 Web application using Visual Studio code in Ubuntu, and run it in Linux containers.


Please enter your comment!
Please enter your name here