Отличный вопрос. Flurl дает вам все необходимые крючки для этого. Сначала определите DelegatingHandler
, который принимает политику Полли:
public class PollyHandler : DelegatingHandler
{
private readonly IAsyncPolicy<HttpResponseMessage> _policy;
public PollyHandler(IAsyncPolicy<HttpResponseMessage> policy) {
_policy = policy;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
return _policy.ExecuteAsync(ct => base.SendAsync(request, ct), cancellationToken);
}
}
Затем создайте пользовательский IHttpClientFactory
, который возвращает ваш пользовательский обработчик с обработчиком по умолчанию в качестве InnerHandler
:
public class PollyFactory : DefaultHttpClientFactory
{
private readonly IAsyncPolicy<HttpResponseMessage> _policy;
public PollyFactory(IAsyncPolicy<HttpResponseMessage> policy) {
_policy = policy;
}
public override HttpMessageHandler CreateMessageHandler() {
return new PollyHandler(_policy) {
InnerHandler = base.CreateMessageHandler()
};
}
}
Наконец, при запуске приложения определите свою политику и зарегистрируйте ее в Flurl:
var policy = Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
.RetryAsync(5);
FlurlHttp.Configure(settings => settings.HttpClientFactory = new PollyFactory(policy));
Одно важное замечание: этот подход не будет работать с политикой, которая обрабатывает FlurlHttpException . Это потому, что вы перехватываете звонки на уровне HttpMessageHandler
здесь. Flurl преобразует ответы и ошибки до FlurlHttpException
s выше по стеку, чтобы при таком подходе они не попали в ловушку / повторную попытку. Политика в приведенном выше примере перехватывает HttpRequestException
и HttpResponseMessage
(с кодами состояния, отличными от 2XX), которые будут работать.