Skip to content

.NET 9 + OpenAPI: InvalidOperationException - cannot resolve IOptionsSnapshot from root provider #66470

@johncrim

Description

@johncrim

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

This issue is touched on here: #58805, thought it takes a while to get to it. There could be multiple issues discussed there. Most importantly, the problem has not been fixed for .NET 9.

This change: cf0b8a5

Needs to be backported to .NET 9. As you can see here, OpenApi 9.0.15 still uses IOptionsSnapshot instead of IOptionsMonitor.
https://github.com/dotnet/aspnetcore/blame/v9.0.15/src/OpenApi/src/Services/OpenApiDocumentProvider.cs

This bug is not logged or reported to the user, it just results in an error when reading an OpenAPI doc (to write to a file).

Expected Behavior

IDocumentProvider.GenerateAsync() can be called outside of a request scoped ServiceProvider.

Steps To Reproduce

The test cases described in #58805 should still reproduce the bug.

Exceptions (if any)

Call stacks:

System.InvalidOperationException
  HResult=0x80131509
  Message=Cannot resolve scoped service 'Microsoft.Extensions.Options.IOptionsSnapshot`1[Microsoft.AspNetCore.OpenApi.OpenApiOptions]' from root provider.
  Source=Microsoft.Extensions.DependencyInjection
  StackTrace:
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(ServiceCallSite callSite, IServiceScope scope, IServiceScope rootScope) in /_/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteValidator.cs:line 26
[System.InvalidOperationException thrown]
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.IServiceScope scope, Microsoft.Extensions.DependencyInjection.IServiceScope rootScope) Line 26
	at /_/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteValidator.cs(26)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceProvider.OnResolve(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.Extensions.DependencyInjection.IServiceScope scope) Line 203
	at /_/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs(203)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier serviceIdentifier, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope serviceProviderEngineScope) Line 212
	at /_/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs(212)
Microsoft.Extensions.DependencyInjection.dll!Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(System.Type serviceType) Line 50
	at /_/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ServiceProviderEngineScope.cs(50)
Microsoft.Extensions.DependencyInjection.Abstractions.dll!Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(System.IServiceProvider provider, System.Type serviceType) Line 45
	at /_/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs(45)
Microsoft.Extensions.DependencyInjection.Abstractions.dll!Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService<Microsoft.Extensions.Options.IOptionsSnapshot<Microsoft.AspNetCore.OpenApi.OpenApiOptions>>(System.IServiceProvider provider) Line 65
	at /_/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs(65)
Microsoft.AspNetCore.OpenApi.dll!Microsoft.Extensions.ApiDescriptions.OpenApiDocumentProvider.GenerateAsync(string documentName, System.IO.TextWriter writer)
[Lightweight Function]
System.Private.CoreLib.dll!System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
Microsoft.WebTools.ApiEndpointDiscovery.dll!Microsoft.WebTools.ApiEndpointDiscovery.OpenApiDocumentGenerator.InvokeMethod(System.Reflection.MethodInfo method, object instance, object[] arguments)
Microsoft.WebTools.ApiEndpointDiscovery.dll!Microsoft.WebTools.ApiEndpointDiscovery.OpenApiDocumentGenerator.WriteOpenApiDocumentAsync(string docGenDirectory, string projectName, string documentName, System.Reflection.MethodInfo generateMethod, object service)
Microsoft.WebTools.ApiEndpointDiscovery.dll!Microsoft.WebTools.ApiEndpointDiscovery.OpenApiDocumentGenerator.GenerateOpenApiDocumentsAsync(string outputDirectory, string projectName, System.IServiceProvider services, System.Threading.CancellationToken cancelToken)
Microsoft.WebTools.ApiEndpointDiscovery.dll!Microsoft.WebTools.ApiEndpointDiscovery.HostingStartup.Configure.AnonymousMethod__1()
[Resuming Async Method]

.NET Version

9.0.305

Anything else?

Microsoft.AspNetCore.App 9.0.15
Microsoft.AspNetCore.OpenApi 9.0.15

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcbugThis issue describes a behavior which is not expected - a bug.feature-openapi

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions