DI NSwag 自动生成客户端的正确方法

mmi*_*mix 10 c# swagger asp.net-core-webapi nswag visual-studio-2022

将 VS 连接服务 (NSwag) 注入类/控制器的首选方法是什么?我在网上找到了很多使用这种形式的建议:

services.AddHttpClient<IClient, Client>((provider, client) =>
    {
        client.BaseAddress = new System.Uri("https://some.baseurl/");
    });
Run Code Online (Sandbox Code Playgroud)

但这会导致错误

{"errorMessage":"Unable to resolve service for type 'System.String' while attempting to activate 'xxx.Client'."}
Run Code Online (Sandbox Code Playgroud)

这来自 中自动生成的客户端类obj,它似乎在构造函数中强制使用字符串 BaseUrl,这当然 DI 无法解析:

public Client(string baseUrl, System.Net.Http.HttpClient httpClient)
{
    BaseUrl = baseUrl;
    _httpClient = httpClient;
    _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
Run Code Online (Sandbox Code Playgroud)

此基本 URL 随后会被强制写入 url 构建器代码中,因此无法真正绕过它。然而,即使网上使用部分扩展客户端类的解决方案似乎也完全忽略了 auto-gen 类中的 baseUrl (就像这里)。就好像它不存在一样(这很奇怪,NSwag 之前生成了不同的构造函数吗?)。该类是通过 csproj 生成的:

  <ItemGroup>
    <OpenApiReference Include="OpenAPIs\swagger.json" CodeGenerator="NSwagCSharp" Namespace="xxx" ClassName="Client">
      <SourceUri>https://localhost:44353/swagger/v1/swagger.json</SourceUri>
    </OpenApiReference>
  </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

这会导致目标构建调用:

2>GenerateNSwagCSharp:
2>  "C:\.<path>./tools/Win/NSwag.exe" openapi2csclient /className:Client /namespace:xxx /input:"C:\<projpath>\OpenAPIs\swagger.json" /output:"obj\swaggerClient.cs"
2>NSwag command line tool for .NET 4.6.1+ WinX64, toolchain v13.13.2.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v11.0.0.0))
Run Code Online (Sandbox Code Playgroud)

那么,这是如何完成的呢?潜在地,在不为代理类创建另一个代理类的情况下,我宁愿让 DI 处理我的对象生命周期。如果可能的话,我还想避免使用 NSwagStudio,并希望保留 VS 提供的工具。

mmi*_*mix 16

好吧,我其实通过摸索解决了这个问题OpenApiReference,但是需要手动修改csproj文件。Options必须添加附加节点OpenApiReference项目组中,以指示 NSwag 不要公开 BaseUrl 并生成一个接口,这可以简化设置 DI 的工作,而无需附加代码。

Visual Studio 团队确实应该将这两个复选框添加到 OpenAPI 的连接服务屏幕/配置中。

<ItemGroup>
  <OpenApiReference Include="OpenAPIs\swagger.json" CodeGenerator="NSwagCSharp" Namespace="xxx" ClassName="Client">
    <SourceUri>https://localhost:44353/swagger/v1/swagger.json</SourceUri>
    <Options>/UseBaseUrl:false /GenerateClientInterfaces:true</Options>
  </OpenApiReference>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

现在只有一个HttpClient构造函数,NSwag 客户端代理使用其中的基地址,因此AddHttpClient可以通过 DI 正常工作。