【问题标题】:Why do NSwag fail on my computer and not on my colleagues for the same C# project?为什么 NSwag 在我的计算机上失败,而不是在同一个 C# 项目的同事上失败?
【发布时间】:2021-06-16 23:30:03
【问题描述】:

我正在开发一个大型 C# Asp.NetCore 3.1 项目,我们使用 Nswag 为我们的 API 生成 swagger.json 和 C# ProxyClient。 突然,我无法再为这个项目生成任何这些文件,因为 NSwag 失败并显示“No service for type”,如下所示。

我尝试将解决方案的新版本 Git 克隆到我机器上的新文件夹中,但问题仍然存在。 当我的同事在他们的机器上做同样的事情时,他们没有问题,因此我们得出结论,这与我们的代码无关。

我创建了一个小的 Asp.NetCore 3.1 API 并添加了我们在原始项目中使用的“openapi.nswag”文件。我没有遇到此解决方案的问题,因此无法重现该错误。

我已经尝试了所有想到的方法: 将 NSwag 更新到最新版本,重新启动计算机,删除 Nswag 并重新安装,清理注册表中与 Nswag 相关的任何内容,尝试使用 NSwagStudio 创建文件。

我的想法真的用完了,所以任何帮助都将不胜感激。

.\nswag run ..\..\openapi.nswag /runtime:NetCore31

NSwag command line tool for .NET Core NetCore31, toolchain v13.7.0.0 (NJsonSchema v10.1.24.0 (Newtonsoft.Json v12.0.0.0))
Visit http://NSwag.org for more information.
NSwag bin directory: C:\Source\MyProgram\src\B2B\B2B.API\node_modules\nswag\bin\binaries\NetCore31

Executing file '..\..\openapi.nswag' with variables ''...

System.InvalidOperationException:没有为类型“Microsoft.Extensions.DependencyInjection.IServiceProviderFactory[Autofac.ContainerBuilder]”注册的服务。 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供程序,类型 serviceType) 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider 提供程序) 在 Microsoft.AspNetCore.Hosting.StartupLoader.ConfigureServicesDelegateBuilder.c__DisplayClass14_0.g__ConfigureServicesWithContainerConfiguration|0(IServiceCollection 服务) 在 Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection 服务) 在 Microsoft.AspNetCore.Hosting.WebHost.EnsureApplicationServices() 在 Microsoft.AspNetCore.Hosting.WebHost.Initialize() 在 Microsoft.AspNetCore.Hosting.WebHostBuilder.Build() 在 C:\projects\nswag\src\NSwag.Commands\Commands\Generation\OpenApiGeneratorCommandBase.cs: 342 中的 NSwag.Commands.Generation.OpenApiGeneratorCommandBase.CreateWebHostAsync(AssemblyLoader assemblyLoader) 在 C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiCommand.cs: 310 中的 NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunIsolatedAsync(AssemblyLoader assemblyLoader) 在 C:\projects\nswag\src\NSwag.Commands\Commands\IsolatedCommandBase.cs 中的 NSwag.Commands.IsolatedCommandBase.IsolatedCommandAssemblyLoader.Run(String commandType, String commandData, String[] assemblyPaths, String[] referencePaths) :第 76 行 在 NSwag.Commands.IsolatedCommandBase.c__DisplayClass17_0.b__0() 在 C:\projects\nswag\src\NSwag.Commands\Commands\IsolatedCommandBase.cs:line 61 在 System.Threading.Tasks.Task.InnerInvoke() 在 System.Threading.Tasks.Task.c.<.cctor>b__274_0(Object obj) 在 System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(线程 threadPoolThread,ExecutionContext executionContext,ContextCallback 回调,对象状态) --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(线程 threadPoolThread,ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 System.Threading.Tasks.Task.ExecuteWithThreadLocal(任务和 currentTaskSlot,线程 threadPoolThread) --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 C:\projects\nswag\src\NSwag.Commands\Commands\IsolatedCommandBase.cs:line 61 中的 NSwag.Commands.IsolatedCommandBase.RunIsolatedAsync(String configurationFile) 在 C:\projects\nswag\src\NSwag.Commands\Commands\IsolatedSwaggerOutputCommandBase.cs: 51 中的 NSwag.Commands.IsolatedSwaggerOutputCommandBase.RunAsync(CommandLineProcessor 处理器,IConsoleHost 主机) 在 C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiCommand.cs:line 95 中的 NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunAsync(CommandLineProcessor 处理器,IConsoleHost 主机) 在 C:\projects\nswag\src\NSwag.Commands\NSwagDocumentBase.cs:line 280 中的 NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() 在 C:\projects\nswag\src\NSwag.Commands\NSwagDocument.cs:line 81 中的 NSwag.Commands.NSwagDocument.ExecuteAsync() 在 C:\projects\nswag\src\NSwag.Commands\Commands\Document\ExecuteDocumentCommand.cs:line 86 中的 NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) 在 C:\projects\nswag\src\NSwag.Commands\Commands\Document\ExecuteDocumentCommand.cs:line 32 中的 NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor 处理器,IConsoleHost 主机) 在 NConsole.CommandLineProcessor.ProcessSingleAsync(字符串 [] 参数,对象输入) 在 NConsole.CommandLineProcessor.ProcessAsync(字符串 [] 参数,对象输入) 在 NConsole.CommandLineProcessor.Process(字符串 [] 参数,对象输入) 在 C:\projects\nswag\src\NSwag.Commands\NSwagCommandProcessor.cs:line 56child_process.js:669 中的 NSwag.Commands.NSwagCommandProcessor.Process(String[] args) 抛出错误;

【问题讨论】:

  • 该错误表明您根本无法运行代码。您是否使用Assembly.Load(..) 在运行时动态加载DLL?因为错误很明显:您没有向 Autofac System.InvalidOperationException: No service for type 'Microsoft.Extensions.DependencyInjection.IServiceProviderFactory&lt;&gt;[Autofac.ContainerBuilder]' has been registered. 注册类型
  • 代码按预期构建和执行。这与我同事计算机上的代码完全相同。
  • Hmmm.. 类型是 Microsoft.Extensions.DependencyInjection.IServiceProviderFactory,它通常是框架的一部分。您是否安装了相同的组件/框架?
  • 是的……完全一样

标签: c# asp.net-core asp.net-core-3.1 openapi nswag


【解决方案1】:

终于在克隆了NSwag并调试之后,发现了问题。

NSwag 正在寻找您要为其创建代理客户端的程序集中的 program 类。它通过refelction 做到这一点,然后NSwag 调用它。 幸运的是,如果 program 抛出异常,它会被 NSwag 抑制,然后运行“后备例程”,通过使用 Assembly 中的 startup 类来创建 Webhost 本身.这样做时,Webhost 不是使用 AutofacServiceProviderFactory 作为 ServiceProviderFactory 创建的,因此抛出了上面的异常而不是初始异常。

在我的情况下,问题是没有设置 ASPNETCORE_ENVIRONMENT 环境变量,因此它不会读取正确的设置。 我的同事全局设置了这个环境变量,但我没有。 原来这个设置可以设置为.nswag配置的一部分

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多