如何将HttpClientFactory与AutoRest生成的客户端一起使用

时间:2019-05-13 12:13:06

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

AutoRest生成的客户端没有合适的构造函数,无法与services.AddHttpClient()方法一起使用。那么我们如何解决这个问题?

现在,我们有了带有此类签名的公共构造函数。

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

但是因为它具有布尔disposeHttpClient参数,所以我们不能在AddHttpClient()方法中直接使用它来将客户端服务配置为DI。 令我深感遗憾的是,HttpClientFactory不包含带有这样签名的方法AddHttpClient的替代版本:

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

2 个答案:

答案 0 :(得分:3)

您需要使用命名客户端,而不是类型客户端,然后您需要使用工厂重载来注册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);
});

答案 1 :(得分:0)

我建议比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);

并定义服务合同用法的单例服务。