Skip to content

[Breaking change]: Runtime host looks for RID-specific assets via a known list instead of RID graph by default #35398

Closed
@elinor-fung

Description

@elinor-fung

Description

When running an application with RID-specific assets, the host determines which assets are relevant for the platform on which it is running. This applies to both the application itself and the resolution logic used by AssemblyDependencyResolver.

Previously, it tried to compute the RID at runtime and then read the RID graph to determine which RID-specific assets match or are compatible with the computed RID. Now, the default behaviour no longer uses the RID graph and a computed RID, relying instead on a known list of RIDs based on how the runtime itself was built.

PR: dotnet/runtime#84100
Related issue: dotnet/runtime#83246
Related design: dotnet/designs#260

Version

.NET 8 Preview 5

Previous behavior

The process for selecting RID-specific assets was:

  1. Read the RID graph from the .deps.json of the root framework (Microsoft.NetCore.App)
  2. Compute the current RID at run-time and try to find an entry for it in the RID graph
    • If it doesn't exist, check for a fallback RID (built into the host at compile-time)
  3. Starting from the entry found in the RID graph, look for assets matching that RID.
  4. Continue down the list of RIDs in the RID graph entry until an asset match is found or the list ends.

This had the effect where if the RID graph didn't have the computed RID or the fallback RID, RID assets would not be properly resolved.

New behavior

By default, the process no longer relies on the RID graph and now checks for a known set of portable RIDs based on how the host was built. For example:

Linux

  • linux-x64
  • linux
  • unix-x64
  • unix
  • any

Windows

  • win-x64
  • win
  • any

macOS

  • osx-x64
  • osx
  • unix-x64
  • unix

For non-portable builds of the host/runtime, the build may also set a non-portable RID that will be checked first.

Type of breaking change

  • Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code may require source changes to compile successfully.
  • Behavioral change: Existing binaries may behave differently at run time.

Reason for change

The RID graph has consistently been costly to maintain and understand, requiring .NET itself to be distro-aware in a fragile manner. The .NET team and the community spend a non-trivial amount of time updating the graph and backporting such updates to previous releases. The long-term goal is to stop updating the RID graph, stop reading it, and eventually remove it. This breaking change is a step towards that goal.

Recommended action

Using portable RIDs (for example, linux, linux-musl, osx, win) is recommended path forwards. For specialized use cases, APIs like NativeLibrary.SetDllImportResolver or AssemblyLoadContext.ResolvingUnmanagedDll can be used for custom loading logic.

A backwards compat switch is also provided to revert to the previous behaviour. Setting the runtime config property System.Runtime.Loader.UseRidGraph to true in a runtimeconfig.json or MSBuild property will use the previous method of reading the RID graph.

Feature area

Deployment

Affected APIs

AssemblyDependencyResolver


Associated WorkItem - 97016

Metadata

Metadata

Assignees

Labels

🏁 Release: .NET 8Work items for the .NET 8 release📌 seQUESTeredIdentifies that an issue has been imported into Quest.binary incompatibleExisting binaries may encounter a breaking change in behavior.breaking-changeIndicates a .NET Core breaking change

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions