-
Notifications
You must be signed in to change notification settings - Fork 10k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable trimming for OpenAPI package #55465
Conversation
@@ -107,6 +107,16 @@ private void ProcessEndpointParameterSource(Endpoint endpoint, ISymbol symbol, I | |||
{ | |||
AssigningCode = "httpContext.Request.Form"; | |||
} | |||
// Complex form binding is only supported in RDF because it uses shared source with Blazor that requires dynamic analysis |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds like it's blaming blazor for dynamic codegen? Does that mean we can make it work by splitting from blazor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minimal APIs shares the same implementation that Blazor uses for complex form binding (see here) which uses reflection. We could implement a source gen layer for form binding but the plan has been to do that in conjunction with Blazor so we're not solving the same problem twice in different ways.
src/OpenApi/src/Extensions/OpenApiEndpointConventionBuilderExtensions.cs
Outdated
Show resolved
Hide resolved
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.OpenApi.Models; | ||
|
||
namespace Microsoft.AspNetCore.OpenApi; | ||
|
||
internal sealed class TypeBasedOpenApiDocumentTransformer(Type transformerType) : IOpenApiDocumentTransformer | ||
internal sealed class TypeBasedOpenApiDocumentTransformer : IOpenApiDocumentTransformer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need the extra field. You can simply add [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
to the parameter, and it will work.
internal sealed class TypeBasedOpenApiDocumentTransformer([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type transformerType) : IOpenApiDocumentTransformer
{
private readonly ObjectFactory _transformerFactory = ActivatorUtilities.CreateFactory(transformerType, []);
public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
{
var transformer = _transformerFactory.Invoke(context.ApplicationServices, []) as IOpenApiDocumentTransformer;
Debug.Assert(transformer != null, $"The type {transformerType} does not implement {nameof(IOpenApiDocumentTransformer)}.");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this but I believe there's an issue at the intersection of primary constructors + linker + DAM attributes:
Trim analysis warning IL2077: Microsoft.AspNetCore.OpenApi.TypeBasedOpenApiDocumentTransformer.TypeBasedOpenApiDocumentTransformer(Type): 'instanceType' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in call to 'Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateFactory(Type, Type[])'. The field 'Microsoft.AspNetCore.OpenApi.TypeBasedOpenApiDocumentTransformer.<_transformerType>P' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a great issue to open. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -7,6 +7,10 @@ | |||
<!-- Needed to support compiling Utf8BufferTextWriter implementation shared with SignalR --> | |||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
<Description>Provides APIs for annotating route handler endpoints in ASP.NET Core with OpenAPI annotations.</Description> | |||
<IsTrimmable>true</IsTrimmable> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<IsTrimmable>true</IsTrimmable> | |
<IsAotCompatible>true</IsAotCompatible> |
We should use this property which will enable all the analzyers. (honestly I thought that's what TrimmableProjects.props
was supposed to be doing...?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my understanding, TrimmableProjects
allows us to explicitly define the list of projects that the LinkabilityChecker will run against. This MSBuild check keeps the TrimmableProjects.props
and IsTrimmable
flags in sync.
As for IsAotCompatible
, I could've sworn there was some MSBuild that was bringing in a PackageReference
and borking the build althoug that doesn't seem to to be the case.
Edit: it's PublishAoT
that brings in the PackageReference
not PublishAoT
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few minor comments. It would be good to log that ILLink Roslyn Analyzer issue. I'll bet more people will run into it with primary constructors becoming popular.
Yep, I'm working on getting a minimal repro with this. Just running the linker on a console project with the buggy scenario doesn't reproduce so I suspect that something about the way our |
Co-authored-by: Eric Erhardt <[email protected]>
Part of #54598.
MapOpenApi
endpoint