Skip to content

Remove RequiresDynamicCode from Microsoft.Extensions.DependencyInjection #79286

@eerhardt

Description

@eerhardt

In .NET 7, with #73829, we annotated Microsoft.Extensions.DependencyInjection as RequiresDynamicCode because it supports enumerable and generic servcies with ValueTypes. When using DI with ValuesTypes, the array and generic code might not be available.

In .NET 8 we need a better approach in order to support applications that use DependencyInjection and publish for NativeAOT. DependencyInjection needs to have reliable behavior before and after publishing for NativeAOT. The application can't work successfully at development-time, but then fail after publishing with PublishAot=true.

Problem

The good thing, there are only limited scenarios where DependencyInjection needs to use dynamic code. And these scenarios are not used very often in real-world applications.

  1. Using "Enumerable" services with ValueTypes. The code currently creates an Array for the enumerable services. The issue is with ValueTypes, there is no guarantee that the runtime has code for an Array of the ValueType.
  2. Using "Open Generic" services with ValuesTypes. The code currently calls MakeGenericType, potentially passing in a ValueType. There is a similar issue here that there is no guarantee that the NativeAOT compiler generated code for the generic type for the ValueType.

Proposal

The proposed approach is similar to how we solved trim-compatibility with DependencyInjection in #55102.

We will resolve the 2 NativeAOT warnings above by adding a runtime check that is behind a new AppContext switch Microsoft.Extensions.DependencyInjection.VerifyAotCompatibility. The runtime check ensures the Types being used with Enumerable and Open Generic services are only Reference Types. If an application tries to create an Enumerable or Closed Generic service of a ValueType, DependencyInjection will throw an exception. The check is enabled by default when PublishAot=true.

The recommendation for applications that want to publish for NativeAOT is to put <PublishAot>true</PublishAot> in their .csproj. That way they get the appropriate analyzers and runtime behaviors during development-time, i.e. F5 in VS or dotnet run from the command line. Applications using the incompatible features above will be broken at development time if the app is intended to be published for AOT. This will give the app developer indication their application won't work after publishing for NativeAOT as well.

cc @davidfowl @halter73 @JamesNK @MichalStrehovsky @agocke @vitek-karas @jkotas

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions