2

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

2 回答 2

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);
});
于 2019-05-13T13:17:25.600 回答
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);

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

于 2019-05-13T18:29:14.813 回答