Closed JTeeuwissen closed 1 week ago
downgrade to previous version if needed
@JTeeuwissen Thanks for reporting this issue!
I believe the issue here might actually be related to the fact that you reference both NSwag.AspNetCore
and Microsoft.AspNetCore.OpenApi
in your project.
The IDocumentProvider
interface is internal and it's up to each OpenAPI implementation to define it in their sources. The lookup logic that we use to resolve the IDocumentProvider
interface through private reflection does so by querying for it across all assemblies that have been loaded in tho the application domain:
I suspect that when the AddOpenApi
method is moved to its own method, it's shifted lower in the list of loaded assemblies and so the codepath above ends up resolving the IDocumentProvider
interface from NSwag's assemblies. Since you never called NSwag's registration method, it fails to resolve one that has been registered.
If you're only using NSwag to serve Swagger UI, I would recommend using Swashbuckle's Swashhbuckle.AspNetCore.SwaggerUi package if you're able to. It splits up the Swagger UI-related APIs into their own assembly so you don't run into any issues with IDocumentProvider
discovery failing.
Can you try swapping out Swashbuckle in your sample app and verifying if that solves the issue for you?
P.S.: I realize the lookup logic in ApiDescription.Server is super spooky given that you can run into issues like this. I'm hoping we can do something drastic to improve the package in the future. See my comment on this issue for more info.
Thank you @captainsafia for the elaborate explanation. Using Swashbuckle I cannot replicate the same issue.
I'm hoping we can do something drastic to improve the package in the future
Is that before the release of dotnet 9?
Is that before the release of dotnet 9?
Unfortunately not....we're already in the release candidate for .NET 9 so the opportunity to merge in major changes isn't there.
Is that before the release of dotnet 9?
Unfortunately not....we're already in the release candidate for .NET 9 so the opportunity to merge in major changes isn't there.
After thinking about it a bit more. Would it be possible to move the
var service = services.GetService(serviceType);
if (service == null)
{
_reporter.WriteError(Resources.FormatServiceNotFound(DocumentService));
return false;
}
part up, so it can be included in the assembly scanning?
Type serviceType = null;
object? service = null;
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
// Try to find the IDocumentProvider in the assembly
var assemblyServiceType = assembly.GetType(DocumentService, throwOnError: false);
if (assemblyServiceType == null) {
continue;
}
serviceType = assemblyServiceType;
// Try to find the IDocumentProvider in the IServiceProvider.
// Multiple assemblies might define an IDocumentProvider but they might not be registered.
service = services.GetService(serviceType);
if (service != null)
{
break;
}
}
if (serviceType == null)
{
_reporter.WriteError(Resources.FormatServiceTypeNotFound(DocumentService));
return false;
}
if (service == null)
{
_reporter.WriteError(Resources.FormatServiceNotFound(DocumentService));
return false;
}
This should have no other impact other than fixing the problem as described in this issue.
@captainsafia ping instead closed issues don't give notifications
Is there an existing issue for this?
Describe the bug
I ran into this bug while trying to use
Microsoft.Extensions.ApiDescription.Server
for openapi file generation.Given this code (see repro for
.sln
)and dependencies
the generation during build fails on resolving the
IDocumentProvider
, although it is registered usingAddOpenApi
. Whenever I inlineMethodThatBreaksBuild
generation works as expected. Similar behavior occurs forMapOpenApi
and conditional execution.Expected Behavior
I expect an
Example.json
to be generated during build, without any errors.Steps To Reproduce
Build this solution
Example.zip
Exceptions (if any)
dotnet build Example.sln
.NET Version
9.0.100-rc.1.24452.12
Anything else?
No response