When you publish a .NET Core project, you can choose between two deployment modes: Framework-Dependent and Self-Contained.

Framework-Dependent deployments are the default and were previously your only choice on .NET Framework. However, .NET Core has added the option of Self-Contained deployments to .NET projects including ASP.NET Core projects.

In this post, I explain the difference between framework-dependent deployments and self-contained deployments, review the pros and cons of each, explain how to configure your project's deployment mode, and finally delve into the deployment differences between .NET Core and .NET Framework.

Two Deployment Modes

Framework-Dependent Deployment

Framework-Dependent deployment is the default deployment option in .NET Core and is the only deployment option for .NET Framework.

In this mode, you deploy portable code that is ready to run in any compatible environment, provided the corresponding framework, either .NET Core or .NET Framework is installed.

The size of the published package is small, as the framework (and runtime) is excluded.

With framework-dependent deployments, the appropriate system installed runtime and framework is used. This has the benefit of decreasing memory usage, as the common components can be shared.

Self-Contained Deployment

Self-Contained deployment is a new deployment option that was added in .NET Core.

In this mode, you compile platform specific code that is ready to run standalone in a specific target environment.

Platform Targets

There are 4 different target platforms available:

  • win-x86
  • win-x64
  • osx-x64
  • linux-x64

.NET Core self-contained deployments will work without any framework being installed on the target system but will only run on systems of the targeted platform. You must create different deployments for different platforms if required.

Package Size

The size of the published package is much larger, as the complete runtime is included in the package. For comparison, I published three packages for a simple sample ASP.NET Core application:

  • Portable / Framework-Dependent - 2.66 MB
  • win-x64 / Self-Contained - 93.1 MB
  • linux-x64 / Self-Contained - 96.3 MB

The self-contained versions were at least 35x bigger!

Version Control

With self-contained deployments, the developer determines the runtime and framework version that will be used, and the application always uses that version as compiled, regardless of what version is installed on the system that runs the code.

If you're using a self-contained deployment, you don't even need to install any runtime or framework at all. For example, if you're following my instructions to setup ASP.NET Core 2.1 on Linux, you can skip step 1, provided you publish a self-contained deployment in step 2.

Pros and Cons

Why use a Self-Contained deployment?

Self-Contained deployments allow you to:

  • Control the exact version of .NET Core used at runtime.
  • Increase reliability by controlling when to upgrade each individual application.
  • Upgrade different applications at different times.

Developer controls the runtime version

The developer has complete control over exactly what version of .NET Core is used and can make sure the application is fully tested in a stable environment before deployment.

Improve Reliability with Controlled Upgrades

Self-Contained deployments make your applications more reliable as you avoid changes in .NET Core updates from changing the behaviour of your deployed applications.

Staggered Upgrades

By using self-contained deployments, you have the opportunity to fully test and update each application to work with a new version as you go. Until you perform the upgrade, the application will continue to operate as it always has.

This lets you update to a newer version for some applications before all applications on the server are tested and ready.

Why use a Framework-Dependent deployment?

Framework-Dependent deployments are portable, much smaller (3 MB vs 93 MB), and different applications share the runtime, which decreases disk and memory usage.

You also get the benefit of framework updates without recompiling and republishing the application.

This allows existing applications to benefit from bug fixes, security patches, and performance enhancements in later releases.

How to configure .NET Core deployment mode

You set the deployment mode when publishing your application.

To configure in Visual Studio:

  1. Right click the project and select Publish.
  2. Select configure next to the target location.
  3. Select the settings tab.
  4. Change the deployment mode as per the 1st screenshot.
  5. Change the target runtime to match the system on which you will run the application as per the 2nd screenshot.

.NET Core Publish Settings - Deployment Mode .NET Core Publish Settings - Target Runtime

Deployment differences between .NET Core and .NET Framework

There are differences between how .NET Core and .NET Framework are installed, and this leads to confusion over what happens when you deploy an application and then upgrade the framework.

Single Version vs Multiple Versions

In .NET Core, you can install different versions of .NET Core on the same machine. This is what was touted as the side-by-side advantage of .NET Core over .NET Framework.

In contrast, .NET Framework 4.x is a Windows component and only one version can be installed on a machine.

You'll sometimes here people say that .NET Framework also supports side-by-side installation. Don't be confused, what they're referring to, is the ability to run the .NET Framework 2.0 and 4.0 runtimes side-by-side. .NET 3.0 and 3.5 use the .NET 2.0 runtime, whereas the newer versions all use the .NET 4.0 runtime.

From this point forward, we'll be considering .NET Framework as referring to only .NET Framework 4.x.

Upgrading .NET Core

When you install a new version of .NET Core, it goes in a new folder alongside the other versions.

Framework-dependent applications will automatically use the latest patch release. So, applications that were running on 2.0.1 will start to use 2.0.2 once it is installed, but not 2.1.0.

Self-contained applications continue to use their respective compiled version, irrespective of what versions are installed on the machine. So self-contained applications compiled against 2.0.1 will continue to use that version, even if 2.0.1 is not installed on the machine and both 2.0.2 and 2.1.0 are installed on the machine.

Upgrading .NET Framework

When you install a newer version of .NET Framework, it replaces the existing version with a new version.

All applications compiled for .NET Framework (4.x) start to run on the new version.

New versions are generally backwards compatible with old versions. This means that applications built on older versions will generally work without modification on newer versions of the framework.

When running an application compiled for an older version on a newer version of the .NET Framework, it will run in compatibility mode. This means it won't get any of the new features.

However, despite running in compatibility mode, an application may still encounter problems from seemingly minor changes. Microsoft describes the situations that can cause problems in their article on version compatibility, which include:

  • performance improvements that expose race conditions
  • hard-coded paths to .NET Framework assemblies
  • reflection on private fields
  • bug fixes
  • security changes

Conclusion

In this post you've learned about the differences between framework-dependent deployments and self-contained deployments in .NET Core. You've also learned about the differences between deployment on .NET Core and .NET Framework.

As we've seen, framework-dependent deployments and self-contained deployments each have their own pros and cons. Different applications and different situations will lend themselves to different deployment types. Make sure you choose which one is most appropriate to your situation.