All articles

.NET Framework or .NET Core: Which Is Better for Your Project?

February 10, 2021

With the release of .NET Core, the question of migration from .NET Framework to .NET Core came up. Many business owners began to think if it’s reasonable to migrate their existing projects and which framework they need for their new projects. In our article, we’ll delve into the discussion.

 .NET Core vs .NET Framework

Cross-platform Compatibility

As far as the most significant differences are concerned,  .NET is now entirely cross-platform.

💡 Since the early beginnings of .NET Framework there was another cross-platform implementation of .NET Framework – Mono. However, while Mono implements ECMA standards for C# and CLR (Common Language Runtime), it isn’t a successor of .NET Framework (like .NET Core) but a trendy and widely adopted alternative.

Though earlier in .NET history, there were .NET Compact Framework used to run on specific Windows devices such as mobile phones, factory controllers, etc., and .NET Micro Framework to run on tiny embedded devices, .NET has never been supported by several general-purpose operating systems families.

Since its first release, .NET Core supported Windows, Linux, and macOS operating systems. The latest version of .NET Core is .NET 5 alongside x86, x64, ARM32, and ARM64 architectures.

Thus, cross-platform support is one of the most significant updates we need to highlight when comparing .NET Core to .NET Framework.

Improved Development Tools

It’s crucial not to consider a framework and its tools as two separate notions. Traditionally, a release of Visual Studio as a primary development environment accompanied each .NET Framework release. However, when Microsoft started its cross-platform invasion, they invested a lot of effort in developing tools to use on all platforms the same way. For example, they released a cross-platform source-code editor Visual Studio Code with corresponding C# extension (powered by OmniSharp) that supports Windows, macOS, and Linux.  In addition to Visual Studio Code, Microsoft also introduced Visual Studio for Mac (formerly Xamarin Studio) as a fully-fledged IDE for .NET and Mobile development on macOS.

Having provided more options for writing code with .NET Core, Microsoft also changed how .NET had been distributed and used before. Strictly speaking, .NET Framework was all in one – every release contained a full set of technologies like WCF, ASP.NET, WPF, etc., and it supported only Windows. So developers used typical Windows development and diagnostics tools like Visual Studio, PerfMon (performance counters), and Windows Event Log to develop and troubleshoot their applications. All extra functionality was installed with NuGet packages. 

In contrast to the aforementioned, .NET Core includes only essential components, heavily relies on the NuGet ecosystem to deliver the rest, and runs on multiple platforms. Such paradigm shifts required significant toolchain revisioning. So alongside .NET Core, Microsoft introduced a .NET CLI, a cross-platform tool for developing, building, running, and publishing .NET applications, and provided a way to extend it with additional command-line .NET Tools (both from Microsoft and community).  

So, now we can use CLI programs to develop, build, run, deploy and diagnose .NET Core applications in the same way on all supported platforms. In addition to a unified way of work, these tools are also updated and released separately, so there is no need to wait for framework releases to get new functionality or bug fixes. 

For information, according to Stackoverflow Surveys 2018-2020, .NET Core is a top-loved tool among developers. It was four positions up in 2019 compared to 2018, and it has held on the top for the last two years.

Source: https://insights.stackoverflow.com/survey

Opportunity for Side-by-side Installation

It’s worth noting that with the emergence of cross-platform support, we can install multiple versions of .NET Core side by side, which is good news for the software development industry. 

Earlier, .NET Framework 2.0, 3.0, and 3.5 were distributed as successive layers of the same installation (they all had the same CLR 2.0, and installation of .NET 3.5 automatically included 2.0 and 3.0). .NET Framework 4.0 created a separate layers hierarchy i.e., each new 4.x version updated represented a new successive layer of 4.0 installation without affecting .NET 3.5 installation. It was still impossible to install multiple framework versions within the same layering installation on the same machine. We often could run an application built using the previous framework version on the machine with a new framework version installed. Still, as it usually happens, you are likely to have some issues because of security changes or bugs introduced in the latest update.

Fortunately, .NET Core solves this problem by allowing multiple versions of .NET Core to be installed on the same device without affecting the system in any way and allowing applications to run on the exact .NET Core version they were built for. 

Self-contained Deployment

Besides side-by-side deployment, .NET Core introduced support for self-contained deployments, allowing developers to bundle applications with everything required to run the app: runtime, components, and libraries.  

The self-contained deployment enables us to copy applications on target systems without any additional installation or configuration of .NET Core runtime. It ensures our application will run on the exact framework version it was built on. It also helps us to gracefully and independently migrate our application from one version of .NET Core to another.

However, the self-contained deployment also makes us responsible for updating our application with the latest .NET Core security improvements and bug fixes.

Better Performance

With .NET Core, its performance has been enhanced prominently. Over the last few years, each release of .NET Core brings more and more performance improvements. Speaking about performance, we take into account these significant aspects:

  • Base Class Library (BCL) consisting of all major types used by programs, including collections, basic types, and classes to connect or transfer data;
  • Runtime including JIT compiler to compile Intermediate Language (MSIL) to machine code), and Garbage Collector (GC) to make sure that the application always has enough memory.

💡 Runtimes consist of many components that are responsible for application execution. However, in terms of performance, BCL, JIT, and Garbage Collector are the parts that get highlighted.

With a new version released, each element performs better. We’ve placed some examples in the table below:

A full list of performance improvements can be found in these blog posts: .NET Core 2.0, .NET Core 2.1, .NET Core 3.0, .NET 5.0.

Besides performance improvements, .NET Core introduces new performance-critical features that had been previously allowed only in an unsafe context. They include Span<T> and Memory<T> types for low-level memory manipulations and stack allocation and hardware intrinsics.

It’s worth mentioning that initially hardware intrinsics were introduced in .NET Core 3.0 but were limited to x86 and x64 architectures; the list was extended in .NET 5 and now there is a separate set for ARM64.

Going to Open Source

Many companies are interested in making .NET Core faster and optimizing its performance, as they need it for their business and applications. Since .NET Core is open-source, many experts contribute to .NET Core growth and development but don’t work for Microsoft. 

To sum it up, we’ve collected all .NET Core updates in the table below:

Considering .NET Core for New Projects

According to Microsoft, .NET Core is the future of .NET, and they anticipate that at least one version of .NET Core will be released each year. So, if it’s a new project, not connected with technologies that .NET Core doesn’t support, it’s worth considering. 

Indeed, certain things aren’t supported by .NET Core. According to Microsoft, they aren’t going to port or reimplement them (however, some technologies have analogs or community open source ports not maintained by Microsoft). 

Here are a few examples:

  • Windows Communication Foundation (WCF)
  • .NET Remoting
  • Code access security (CAS) and security transparency
  • Workflow Foundation (WF)

(You can find a full list of unsupported technologies here.)

In general, it’s hard to find reasons why you can’t use.NET Core for new projects. Moreover, migrating to an updated version is simple enough, and companies will only leverage it. So, it’s better to choose .NET Core for new projects rather than .NET Framework. 

Besides, .NET Core is suitable not only for cross-platform applications but also for desktop app development. Since the .NET Core 3.0 version, Microsoft has provided opportunities for desktop development for Windows. The company also ported Windows Forms and WPF technology in .NET Core. 

Speaking about other reasons you should consider .NET Core, not .NET Framework, we also need to mention cost-effectiveness. More and more modern applications are cloud-oriented, and it’s quite expensive to have Windows-based applications in a cloud because of higher resources requirement, licensing fees, etc. Using Linux can reduce cloud infrastructure costs by lowering operating systems resource requirements (or if talking about containerized applications, it will also reduce image size) and removing license fees.

The fun fact is that .NET Core was one position up in 2019 compared to 2018, but surprisingly, was superseded by  .NET. Looks like the Framework is back in game.🙂

Source: https://insights.stackoverflow.com/survey

Migrating existing applications to .NET Core

First of all, you need to analyze your project to understand if you need to migrate. It’s crucial to define the goal of migration to .NET Core. For example, suppose you need to migrate because the goal is to benefit from running the application on Linux. In that case, it could be quite complicated or even impossible as you need to make sure your application doesn’t use Windows-specific features and technologies not supported by .NET Core. 

In case migration to .NET Core is needed to gain all its benefits but remain on Windows, this kind of process could be quite friendly because Microsoft provides a special Windows Compatibility Pack with many Windows-specific API found only in .NET Framework. 

However, it is still worth keeping in mind that .NET Core doesn’t include some of .NET Framework technologies.  Despite the analogies offered by Microsoft or the community, they could be unsuitable for certain applications (i.e.,   Microsoft recommends switching to gRPC for simple WCF scenarios). Nevertheless, if you can’t port any part of your application, it doesn’t mean you can’t develop new services and components using .NET Core and .NET Standard. 

Conclusion

No doubt, .NET Core is more progressive and brings more software development opportunities, including cross-platform software development, side-by-side deployment, better performance, etc. Still, considering migrating your .NET Framework project to .NET Core, you need to view all the pros and cons to understand if it’s reasonable and cost-effective.

Links and related resources

  1. https://www.mono-project.com/
  2. https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/versions-and-dependencies
  3. https://docs.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained
  4. https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core/
  5. https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-2-1/
  6. https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-3-0/
  7. https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/
  8. https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#tiered-compilation
  9. https://docs.microsoft.com/en-us/dotnet/core/porting/net-framework-tech-unavailable?toc=/dotnet/fundamentals/toc.json&bc=/dotnet/breadcrumb/toc.json
  10. https://docs.microsoft.com/en-us/dotnet/core/porting/windows-compat-pack
  11. https://docs.microsoft.com/en-us/dotnet/standard/net-standard

by Oleg Karasik

;

Oleg is a .NET Tech Lead with more than ten years of experience in developing enterprise-level web applications, frameworks, shared libraries, and utilities of different scale. Besides coding, Oleg runs his tech blog and creates a monthly newsletter (named .NET R&D Digest), including links to blog posts and articles, books, tools, and other interesting .NET related (and sometimes not) stuff. Follow him on Twitter to get tech updates.