【问题标题】:Proper way to DI NSwag auto-generated clientDI NSwag 自动生成客户端的正确方法
【发布时间】:2021-11-18 19:32:32
【问题描述】:

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

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

但是这会导致错误

{"errorMessage":"Unable to resolve service for type 'System.String' while attempting to activate 'xxx.Client'."}

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

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

此基本 URL 稍后会强制进入 url 构建器代码,因此无法真正绕过它。然而,即使是网络上使用部分扩展客户端类的解决方案似乎也完全忽略了 auto-gen 类中的 baseUrl(如here)。好像它不存在(这很奇怪,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>

这会导致目标构建调用:

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))

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

【问题讨论】:

  • 请停止删除我的 visual-studio-2022 标签。这在 2019 年完美运行,这是一个回归问题。

标签: c# swagger asp.net-core-webapi nswag visual-studio-2022


【解决方案1】:

由于生成的类被标记为部分,您可以提供额外的构造函数并使用[ActivatorUtilitiesConstructor] 属性对其进行标记。应用属性确保构造函数与依赖注入一起使用。您还可以在部分扩展中实现该接口。这是一个例子;

public partial class MyApiClient : IMyApiClient
{
    [ActivatorUtilitiesConstructor] // This ctor will be used by DI
    public MyApiClient(HttpClient httpClient, IOptions<MyApiClientOptions> clientOptions)
    : this(clientOptions.Value.Url, httpClient) // Call generated ctor
    {
    }
}

【讨论】:

  • 我接受它作为一个可行的解决方案,但是,我认为我不应该编写代码来修复 IDE 中的回归问题。 swagger 本身支持这个代码生成过程,这是 Visual Studio 2022 不再支持它的问题。我已经和他们开了一张票,但像往常一样,他们忽略了它。
【解决方案2】:

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

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

<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>

现在只有HttpClient构造函数,NSwag客户端代理使用它的基地址,所以AddHttpClient通过DI正常工作。

【讨论】:

    猜你喜欢
    • 2022-07-11
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    相关资源
    最近更新 更多