Skip to content

Write framework references for self-contained apps #3541

Closed
@vitek-karas

Description

@vitek-karas

Problem

This is continuation of issue originally described in dotnet/core-setup#7610 and the SDK counterpart to dotnet/core-setup#7732.
When the native host loads a .NET Core component into already running .NET Core app, it tries to validate that the component's framework references can be satisfied by the app. In order to do this it needs to know which frameworks the app is using. For framework dependent apps this is trivial as the host knows which frameworks it resolved for the app. For self-contained apps though, there's no information about frameworks.

Currently framework dependent console app has .runtimeconfig.json like this:

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.0",
    "frameworks":
    [
      {
        "name": "Microsoft.NETCore.App",
        "version": "3.0.0"
      }
    ]
  }
}

A self-contained app on the other hand has .runtimeconfig.json like this:

{
  "runtimeOptions": {}
}

Proposal

Write the same information even for self-contained apps. The caveat is that framework references should not be written the exact same way otherwise host will think it's a framework dependent application (self-contained apps are recognized through the fact that they have no framework references).

Write the tfm property

This would make self-contained apps behave consistently with framework dependent apps. The TFM is not used widely by the host, but it does come into play in specific cases around additional probe paths and DOTNET_SHARED_STORE functionality.

Compatibility note: It's not really a breaking change if we start writing the tfm property. It does change the behavior of the app slightly, but in order for it to take effect the app has to be rebuilt, so there's an explicit action by the developer.

Write a new includedFrameworks property

Framework references in self-contained apps would be written to a new property includedFrameworks which would use the same syntax. It's an array of objects, where each object represents a framework reference. The framework reference must specify its name and version. Other properties like rollForward which are allowed on normal framework references will not be allowed here.

Compatibility note: Combined with the changes in the host to consume this property, it will change behavior of apps when trying to load dynamic components. But the change requires a rebuild of the app in question, so it's not a breaking change.

The final .runtimeconfig.json would look like this:

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.0",
    "includedFrameworks":
    [
      {
        "name": "Microsoft.NETCore.App",
        "version": "3.0.0"
      }
    ]
  }
}

Naming is always an interesting question, so includedFrameworks is just one option. It could be called embeddedFrameworks, containedFrameworks, ... other suggestions are very welcome. The name should be somewhat clear about the fact that the framework is part of the app.

Impact

The proposed change makes the .runtimeconfig.json bigger for self-contained apps, but the change is tiny (100s of bytes).

Performance wise there is some cost to write it in the SDK, but that it very small compared to the rest of the work SDK does. The host has to parse the new information as well, so there's some cost to that, but it doesn't have to process it (just remember) during startup, so the perf impact on startup should be very small.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions