RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.79k stars 1.29k forks source link

No service for type 'Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionGroupCollectionProvider' has been registered #3737

Closed dmitry-pavlov closed 2 years ago

dmitry-pavlov commented 2 years ago

I am getting No service for type 'Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionGroupCollectionProvider' has been registered exception on MS Build post build event from NSwag target for unclear reason.

The projects structure - 2 projects API and class library:

MyNET5WebAPI dir - .NET 5 Web API project with post build MS Build NSwag target MyNET5WebAPI.Clients dir - .NET 5 Class library project with nswag.json and where generated output goes

Re: error - I have tried adding to DI what errors states to Startup.ConfigureServices both way:

services.AddMvcCore().AddApiExplorer();

as wels as:

services.TryAddSingleton<IApiDescriptionGroupCollectionProvider, ApiDescriptionGroupCollectionProvider>();
services.TryAddEnumerable(ServiceDescriptor.Transient<IApiDescriptionProvider, DefaultApiDescriptionProvider>());

Questions:

  1. I don't understand why NSwag can't get this IApiDescriptionGroupCollectionProvider from DI - any pointers?
  2. What makes NSwag generators requiring this IApiDescriptionGroupCollectionProvider? I mean what in my API project is causing to require this dependency at all?

The same setup used to work a week ago, I see no OpenApi related changes, but had recently updated to major 5 versions for most of the NuGet packages.

What am I missing? Any ideas are much appreciated.

1>dotnet "C:\Users\dimak\.nuget\packages\nswag.msbuild\13.14.4\build\../tools/Net50/dotnet-nswag.dll" run ../MyNET5WebAPI.Clients/nswag.json /variables:Configuration=Debug
1>NSwag command line tool for .NET Core Net50, toolchain v13.14.4.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v12.0.0.0))
1>Visit http://NSwag.org for more information.
1>NSwag bin directory: C:\Users\dimak\.nuget\packages\nswag.msbuild\13.14.4\tools\Net50
1>
1>Executing file '../MyNET5WebAPI.Clients/nswag.json' with variables 'Configuration=Debug'...
1>Launcher directory: C:\Users\dimak\.nuget\packages\nswag.msbuild\13.14.4\tools\Net50
1>System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
1> ---> System.InvalidOperationException: No service for type 'Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionGroupCollectionProvider' has been registered.
1>   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
1>   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
1>   at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.GenerateDocumentWithApiDescriptionAsync(AssemblyLoader assemblyLoader, IServiceProvider serviceProvider, String currentWorkingDirectory) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiCommand.cs:line 309
1>   at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.GenerateDocumentAsync(AssemblyLoader assemblyLoader, IServiceProvider serviceProvider, String currentWorkingDirectory) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiCommand.cs:line 293
1>   at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiGeneratorCommandEntryPoint.<>c__DisplayClass0_0.<<Process>b__0>d.MoveNext() in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiGeneratorCommandEntryPoint.cs:line 32
1>--- End of stack trace from previous location ---
1>   at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiGeneratorCommandEntryPoint.Process(String commandContent, String outputFile, String applicationName) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiGeneratorCommandEntryPoint.cs:line 31
1>   --- End of inner exception stack trace ---
1>   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
1>   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
1>   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
1>   at NSwag.AspNetCore.Launcher.Program.Main(String[] args) in C:\projects\nswag\src\NSwag.AspNetCore.Launcher\Program.cs:line 170
1>System.InvalidOperationException: Swagger generation failed with non-zero exit code '1'.
1>   at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiCommand.cs:line 231
1>   at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in C:\projects\nswag\src\NSwag.Commands\NSwagDocumentBase.cs:line 280
1>   at NSwag.Commands.NSwagDocument.ExecuteAsync() in C:\projects\nswag\src\NSwag.Commands\NSwagDocument.cs:line 81
1>   at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in C:\projects\nswag\src\NSwag.Commands\Commands\Document\ExecuteDocumentCommand.cs:line 85
1>   at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:\projects\nswag\src\NSwag.Commands\Commands\Document\ExecuteDocumentCommand.cs:line 32
1>   at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
1>   at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
1>   at NConsole.CommandLineProcessor.Process(String[] args, Object input)
1>   at NSwag.Commands.NSwagCommandProcessor.Process(String[] args) in C:\projects\nswag\src\NSwag.Commands\NSwagCommandProcessor.cs:line 55
1>D:\src\MyNET5WebAPI\MyNET5WebAPI.csproj(77,9): error MSB3073: The command "dotnet "C:\Users\dimak\.nuget\packages\nswag.msbuild\13.14.4\build\../tools/Net50/dotnet-nswag.dll" run ../MyNET5WebAPI.Clients/nswag.json /variables:Configuration=Debug" exited with code -1.
dmitry-pavlov commented 2 years ago

My MSBuild target in MyNET5WebAPI project refers to nswag.json in MyNET5WebAPI.Clients project and looks like this:

    <Target Name="NSwag" BeforeTargets="AfterBuild" Condition="'$(GenerateApiClient)'!='False' ">
        <Exec Command="$(NSwagExe_Net50) run ../MyNET5WebAPI.Clients/nswag.json /variables:Configuration=$(Configuration) /runtime:Net50" />
    </Target>
dmitry-pavlov commented 2 years ago

The root of the evil was the wrong value for aspNetCoreEnvironment setting, which somehow was causing issues with resolving services from DI. Once I set the right value (in my case environment name was 'LocalDevelopment') NSwag MSBuild target got fixed and started working OK.

  "aspNetCoreEnvironment": "LocalDevelopment"

image

P.S. It is still confusing me as the reason is totally unclear (at least to me), but hope this helps someone else experiencing this "magic".

Closing the issue.