Runtime-specific apps no longer self-contained
Runtime-specific apps, or .NET apps with a RuntimeIdentifier
, are no longer self-contained by default. Instead, they are framework-dependent by default.
This is a breaking change in the following situations:
- If you deployed, distributed, or published your app and didn't explicitly add the
SelfContained
property, but also didn't require that the .NET runtime be installed on the machine for it to work. In this case, you may have relied on the previous behavior to produce a self-contained app by default. - If you rely on the IL Link tool. In this case, take the steps described under Recommended action to use IL Link again.
Previous behavior
Previously, if a runtime identifier (RID) was specified (via RuntimeIdentifier), the app was published as self-contained, even if SelfContained
wasn't explicitly specified.
In addition:
- If
PublishSelfContained
wasn't explicitly set tofalse
, the publish propertiesPublishSingleFile
andPublishAot
implied aRuntimeIdentifier
and thereforeSelfContained
(if it wasn't specified) during operations includingdotnet build
,dotnet restore
, anddotnet publish
. - The
PublishTrimmed
property did not implySelfContained
. - The
PublishReadyToRun
property impliedSelfContained
ifSelfContained
wasn't specified.
New behavior
Starting in .NET 8, for apps that target .NET 8 or a later version, RuntimeIdentifier
no longer implies SelfContained
by default. Instead, apps that specify a runtime identifier are dependent on the .NET runtime by default (framework-dependent). Apps that target .NET 7 or earlier versions aren't affected.
In addition:
- If
PublishSelfContained
isn't explicitly set tofalse
, the publish propertiesPublishSingleFile
andPublishAot
now implySelfContained
(if it's not specified) duringdotnet publish
only (that is, not fordotnet build
ordotnet restore
). - The
PublishTrimmed
property also now impliesSelfContained
duringdotnet publish
. - The
PublishReadyToRun
property no longer impliesSelfContained
if the project targets .NET 8 or later.
Note
If you publish using msbuild /t:Publish
and you want your app to be self-contained, you must explicitly specify SelfContained
, even if your project has one of the listed publish properties.
Version introduced
.NET 8 Preview 5
Type of breaking change
This change can affect source compatibility and binary compatibility.
Reason for change
- The new .NET SDK behavior aligns with Visual Studio behavior.
- Framework-dependent apps are smaller by default, since there aren't copies of .NET stored in each app.
- When .NET is managed outside of the app (that is, for framework-dependent deployments), .NET stays more secure and up-to-date. Apps that have their own copy of the runtime don't get security updates. This change makes more apps framework-dependent by default.
- Ideally, command-line options are orthogonal. In this case, the tooling supports both RID-specific self-contained deployment (SCD) and RID-specific framework-dependent deployment (FDD). So it didn't make sense that no RID defaulted to FDD and RID defaulted to SCD. This behavior was often confusing for users.
.NET 6 alerted users to this breaking change with the following warning:
warning NETSDK1179: One of '--self-contained' or '--no-self-contained' options are required when '--runtime' is used.
Now that customers have had time to add SelfContained
explicitly, it's okay to introduce the break.
Recommended action
If you're using .NET 7 or an earlier version and relied on the previous behavior where
SelfContained
was inferred, you'll see this warning:For projects with TargetFrameworks >= 8.0, RuntimeIdentifier no longer automatically gives a SelfContained app. To continue creating a .NET framework independent app after upgrading to 8.0, consider setting SelfContained explicitly.
Follow the guidance of the warning and declare your app as self-contained. You can do that either in the project file or as a command-line argument, for example,
dotnet publish --self-contained
.If you're using .NET 8 and want to keep the previous behavior, set
SelfContained
totrue
in the same way as previously described.
Set project-file property
SelfContained
is an MSBuild property that you can insert into your project file, which is a file that has a .csproj, .vbproj, or .fsproj extension. Set the property as follows:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<SelfContained>true</SelfContained>
</PropertyGroup>
</Project>