Skip to content

[Bug]: SwaggerGen filters throw constructer exception from AoT published application #3572

@a-priestley

Description

@a-priestley

Describe the bug

Registering .AddSwaggerGen(options => ...) adding filters, eg: options.DocumentFilter<MyFilter>() results in constructor location failures for the filter when running a published application with AoT compilation enabled.

Expected behavior

No response

Actual behavior

No response

Steps to reproduce

Sample repo:
https://github.com/a-priestley/swashbuckle-aot

Publish the application:

dotnet publish -o ./output

Run:

./output/[executable]

Navigate to docs page ([host]/swagger) in browser, observe exception in stdout.

Exception(s) (if any)

info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'HTTP: GET /swagger/{documentName}/swagger.{extension:regex(^(json|ya?ml)$)}'
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HNFLTL8QLGKA", Request id "0HNFLTL8QLGKA:00000004": An unhandled exception was thrown by the application.
      System.InvalidOperationException: A suitable constructor for type 'MyDocumentFilter' could not be located. Ensure the type is concrete and all parameters of a public constructor are either registered as services or passed as arguments. Also ensure no extraneous arguments are provided.
         at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(Type, Type[], ActivatorUtilities.ConstructorInfoEx[], ConstructorInfo&, Nullable`1[]&) + 0xac
         at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[]) + 0x49d
         at Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions.GetOrCreateFilter[TFilter](FilterDescriptor) + 0x29
         at Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions.Configure(SwaggerGeneratorOptions) + 0x335
         at Microsoft.Extensions.Options.OptionsFactory`1.Create(String) + 0x91
         at Microsoft.Extensions.Options.UnnamedOptionsManager`1.get_Value() + 0xa2
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite, RuntimeResolverContext) + 0xe
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x79
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite, RuntimeResolverContext) + 0xe
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider, Type) + 0x3d
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider) + 0x2f
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite, RuntimeResolverContext) + 0xe
         at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.GetService(IServiceProvider, Type, Type) + 0x1f
         at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass9_0`1.<ReflectionFallback>b__0(T, HttpContext, IServiceProvider) + 0xb5
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) + 0x48c
         at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.<Invoke>d__6.MoveNext() + 0x10e
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<ProcessRequests>d__237`1.MoveNext() + 0x3e7

Swashbuckle.AspNetCore version

9.0.4

.NET Version

tested with net9.0 and net10.0 target frameworks

Anything else?

Using a filter instance:

c.AddDocumentFilterInstance<MyDocumentFilter>(new());

Does not result in this exception, but we lose dependency injection capabilities in the filter constructor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions