【问题标题】:How to use HttpClientFactory with AutoRest generated client如何将 HttpClientFactory 与 AutoRest 生成的客户端一起使用
【发布时间】:2019-09-30 09:37:00
【问题描述】:

AutoRest 生成的客户端没有合适的构造函数来使用 services.AddHttpClient() 方法。那么我们该如何解决呢?

现在我们有了带有这样签名的公共构造函数。

public Client(ServiceClientCredentials credentials, HttpClient httpClient, bool disposeHttpClient) : this(httpClient, disposeHttpClient)

但是因为它有 bool disposeHttpClient 参数,我们不能直接在 AddHttpClient() 方法中使用它来将客户端服务配置到 DI 中。 令我深感遗憾的是,HttpClientFactory 不包含具有此类签名的方法 AddHttpClient 的覆盖版本:

AddHttpClient<IClient>(Func<IServiceProvider, HttpClietn, IClient> configClient)

【问题讨论】:

    标签: c# asp.net-core dependency-injection autorest httpclientfactory


    【解决方案1】:

    您需要使用命名客户端,而不是类型化客户端,然后您需要使用工厂重载注册 AutoRest 客户端。

    services.AddHttpClient("MyAutoRestClient", c =>
    {
        // configure your HttpClient instance
    });
    
    services.AddScoped<MyAutoRestClient>(p =>
    {
        var httpClient = p.GetRequiredService<IHttpClientFactory>().GetClient("MyAutoRestClient");
        // get or create any other dependencies
        // set disposeHttpClient to false, since it's owned by the service collection
        return new MyAutoRestClient(credentials, httpClient, false);
    });
    

    【讨论】:

      【解决方案2】:

      我建议比 Chris Patt 更优雅的解决方案。我们可以从生成的类继承并定义适合 DI 和 AddHttpClient() ctr。请参阅下面的代码。

      public partial class MyAutoRestClientExtended: MyAutoRestClient
      {
          public MyAutoRestClientExtended(HttpClient httpClient, IOptions<SomeOptions> options)
              : base(new EmptyServiceClientCredentials(), httpClient, false)
          {
              var optionsValue = options.Value ?? throw new ArgumentNullException(nameof(options));
              BaseUri = optionsValue .Url;
          }
      }
      

      现在我们可以使用 AddHttpClient() 方法通过流畅的方式构建器配置类型化客户端,其所有优点如 Polly 策略定义和 HttpHandler 定义。

      services.AddHttpClient<MyAutoRestClientExtended>()
                         .ConfigureHttpClient((sp, httpClient) =>
                         {                         
                             httpClient.Timeout = TimeSpan.FromSeconds(30);
                         })
                         .SetHandlerLifetime(TimeSpan.FromMinutes(5))
                         .ConfigurePrimaryHttpMessageHandler(x => new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate })
                         .AddHttpMessageHandler(sp => sp.GetService<AuthenticationHandlerFactory>().CreateAuthHandler())
                         .AddPolicyHandlerFromRegistry(PollyPolicyName.HttpRetry)
                         .AddPolicyHandlerFromRegistry(PollyPolicyName.HttpCircuitBreaker);
      

      并为服务合同使用定义单例服务。

      【讨论】:

        猜你喜欢
        • 2018-11-06
        • 2016-11-05
        • 2021-06-05
        • 2017-10-03
        • 2020-01-31
        • 2016-06-18
        • 2019-03-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多