diff --git a/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs b/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs index c8df1cab87af..cdbdded757af 100644 --- a/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs +++ b/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs @@ -341,6 +341,7 @@ static void InvokeContainer(GenericWebHostBuilder genericWebHostBuilder, Configu { var containerType = configureContainerBuilder.GetContainerType(); + // Configure container uses MakeGenericType with the container type. MakeGenericType + struct container type requires IsDynamicCodeSupported. if (containerType.IsValueType && !RuntimeFeature.IsDynamicCodeSupported) { throw new InvalidOperationException("A ValueType TContainerBuilder isn't supported with AOT."); diff --git a/src/Hosting/Hosting/src/Internal/StartupLoader.cs b/src/Hosting/Hosting/src/Internal/StartupLoader.cs index 8a5332be0470..7ce94001b02e 100644 --- a/src/Hosting/Hosting/src/Internal/StartupLoader.cs +++ b/src/Hosting/Hosting/src/Internal/StartupLoader.cs @@ -68,6 +68,7 @@ public static StartupMethods LoadMethods(IServiceProvider hostingServiceProvider Justification = "There is a runtime check for ValueType startup container. It's unlikely anyone will use a ValueType here.")] static Type CreateConfigureServicesDelegateBuilder(Type type) { + // Configure container uses MakeGenericType with the container type. MakeGenericType + struct container type requires IsDynamicCodeSupported. if (type.IsValueType && !RuntimeFeature.IsDynamicCodeSupported) { throw new InvalidOperationException("ValueType startup container isn't supported with AOT."); diff --git a/src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs b/src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs index 757136767129..26f1b4db5aad 100644 --- a/src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs +++ b/src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs @@ -109,7 +109,9 @@ public static IApplicationBuilder UseMiddleware( return (RequestDelegate)invokeMethod.CreateDelegate(typeof(RequestDelegate), instance); } - var factory = RuntimeFeature.IsDynamicCodeSupported + // Performance optimization: Use compiled expressions to invoke middleware with services injected in Invoke. + // If IsDynamicCodeCompiled is false then use standard reflection to avoid overhead of interpreting expressions. + var factory = RuntimeFeature.IsDynamicCodeCompiled ? CompileExpression(invokeMethod, parameters) : ReflectionFallback(invokeMethod, parameters); diff --git a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs index 201260c7ce7f..f3c60b48473d 100644 --- a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs +++ b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs @@ -422,6 +422,7 @@ private static Expression[] CreateArgumentsAndInferMetadata(MethodInfo methodInf for (var i = 0; i < argTypes.Length; i++) { + // MakeGenericMethod + value type requires IsDynamicCodeSupported to be true. if (RuntimeFeature.IsDynamicCodeSupported) { // Register expressions containing the boxed and unboxed variants @@ -560,7 +561,7 @@ private static Expression CreateEndpointFilterInvocationContextBase(RequestDeleg DefaultEndpointFilterInvocationContextConstructor, new Expression[] { HttpContextExpr, paramArray }); - if (!RuntimeFeature.IsDynamicCodeCompiled) + if (!RuntimeFeature.IsDynamicCodeSupported) { // For AOT platforms it's not possible to support the closed generic arguments that are based on the // parameter arguments dynamically (for value types). In that case, fallback to boxing the argument list. diff --git a/src/Http/Routing/src/Matching/JumpTableBuilder.cs b/src/Http/Routing/src/Matching/JumpTableBuilder.cs index 11b013979a0a..b08d4ec0eb05 100644 --- a/src/Http/Routing/src/Matching/JumpTableBuilder.cs +++ b/src/Http/Routing/src/Matching/JumpTableBuilder.cs @@ -92,6 +92,8 @@ public static JumpTable Build(int defaultDestination, int exitDestination, (stri [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Guarded by IsDynamicCodeCompiled")] static JumpTable MakeILEmitTrieJumpTableIfSupported(int defaultDestination, int exitDestination, (string text, int destination)[] pathEntries, JumpTable fallback) { + // ILEmitTrieJumpTable use IL emit to generate a custom, high-performance jump table. + // EL emit requires IsDynamicCodeCompiled to be true. Fallback to another jump table implementation if not available. return RuntimeFeature.IsDynamicCodeCompiled ? new ILEmitTrieJumpTable(defaultDestination, exitDestination, pathEntries, vectorize: null, fallback) : fallback; diff --git a/src/Shared/PropertyHelper/PropertyHelper.cs b/src/Shared/PropertyHelper/PropertyHelper.cs index 0b752424d55e..027066a6d1d7 100644 --- a/src/Shared/PropertyHelper/PropertyHelper.cs +++ b/src/Shared/PropertyHelper/PropertyHelper.cs @@ -211,6 +211,7 @@ public static PropertyHelper[] GetVisibleProperties( Debug.Assert(!getMethod.IsStatic); Debug.Assert(getMethod.GetParameters().Length == 0); + // MakeGenericMethod + value type requires IsDynamicCodeSupported to be true. if (RuntimeFeature.IsDynamicCodeSupported) { // TODO: Remove disable when https://github.com/dotnet/linker/issues/2715 is complete. @@ -285,6 +286,7 @@ public static PropertyHelper[] GetVisibleProperties( var parameters = setMethod.GetParameters(); Debug.Assert(parameters.Length == 1); + // MakeGenericMethod + value type requires IsDynamicCodeSupported to be true. if (RuntimeFeature.IsDynamicCodeSupported) { // TODO: Remove disable when https://github.com/dotnet/linker/issues/2715 is complete.