【问题标题】:How Setup Parameters for AddHttpClient when IHttpClientFactory is created?创建 IHttpClientFactory 时如何为 AddHttpClient 设置参数?
【发布时间】:2019-04-02 18:25:38
【问题描述】:

我正在尝试设置一个 IHttpClientFactory,我想知道在创建它时如何向它发送参数,这些参数我需要分配给重试策略。

我正在使用 .Net Core 2.2 和 Microsoft.Extensions.Http.Polly,我已阅读此帖子 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2

我有这是 Startup.cs

services.AddHttpClient("MyClient", c =>
{
    c.BaseAddress = new Uri("http://interface.net");
    c.DefaultRequestHeaders.Add("Accept", "application/json");
})
.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));

我是这样用的

private readonly IHttpClientFactory _iHttpClientFactory;

public ValuesController(IHttpClientFactory iHttpClientFactory)
{
    _iHttpClientFactory = iHttpClientFactory;
}

public async Task<ActionResult<string>> Get()
{
    var client = _iHttpClientFactory.CreateClient("MyClient");
    var response = await client.GetAsync("/Service?Id=123");
    response.EnsureSuccessStatusCode();
    var result = await response.Content.ReadAsStringAsync();
    return result;
}

我想知道当我执行 CreateClient 时是否有办法发送参数,用于在 AddTransientHttpErrorPolicy 中分配给 retryCount 和 sleepDuration,在这种情况下分别为 3 和 600,因为我需要创建具有不同 retryCounts 的客户端和 sleepDurations,这些值可以改变。

类似的东西

var retryCount = 5;
var sleepDuration = 400;
var client = _iHttpClientFactory.CreateClient("MyClient", retryCount, sleepDuration);

或者其他方式?

【问题讨论】:

标签: c# asp.net-core dotnet-httpclient polly


【解决方案1】:

据我所知,你不能。 IHttpClientFactory 的工作原理并不是这样。这个想法是为特定场景提供可重用的客户端,而不是在不同场景之间共享的无限可配置客户端,Polly 配置几乎与此一致。

换句话说,设计是您可以为一个或多个客户端配置各种重试策略等您想要的,然后您可以指定特定场景需要哪些重试策略。

services.AddHttpClient("MyClient", c =>
{
    c.BaseAddress = new Uri("http://interface.net");
    c.DefaultRequestHeaders.Add("Accept", "application/json");
})
.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));

services.AddHttpClient("MyClient2", c =>
{
    c.BaseAddress = new Uri("http://interface.net");
    c.DefaultRequestHeaders.Add("Accept", "application/json");
})
.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(5, _ => TimeSpan.FromMilliseconds(400)));

然后,您可以使用"MyClient""MyClient2" 调用CreateClient。为了避免在主客户端配置中重复自己,您可以排除正文:

Action<HttpClient> myClientConfig = c =>
{
    ...
}

然后:

services.AddHttpClient("MyClient", myClientConfig);

或者,您可以考虑创建自定义扩展:

public static IHttpClientBuilder AddMyClient(this IServiceCollection services, string clientName)
{
    return services.AddHttpClient(clientName, c =>
    {
        ...
    });
}

然后:

services.AddMyClient("MyClient")
    .AddTransientHttpErrorPolicy(...);

不过,总的来说,Polly 策略几乎应该与特定用例绑定。您将知道特定的 API/端点需要什么,并且您将直接围绕它构建策略。不同的 API/端点可能需要不同的处理,但在这种情况下,这是不同客户端的参数。

【讨论】:

  • 好的,我想避免这种情况,但如果没有其他办法,我将不得不这样做。感谢您的宝贵时间
  • 重点是这很可能是您的设计问题。不需要为特定的客户端配置制定不同的策略。如果 API 上的各个端点或其他任何东西之间存在如此大的差异,那么就可以验证为每个场景定制了多个不同的客户端。
  • 抱歉,我的回复延迟了。这不是设计问题,而是业务要求。我的服务将使用一个 API,我无法修改该 API。其他服务将使用我创建的服务,并且他们想向我发送重试次数和睡眠持续时间,因为这些服务具有不同的超时和响应时间。现在,我使用您的建议,我为每项服务配置了客户端,即使是没有重试策略的服务,我从环境变量中获取值,因此它们很容易更改
猜你喜欢
  • 2020-02-15
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
  • 2011-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多