本文介绍了使用Flurl设置默认的Polly策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在一起使用Polly和Flurl,但是我有一个通用的重试策略,必须将其添加到每个请求中.我注意到Polly允许您使用AddPolicyHandler(...)设置默认值,但这需要IHttpClientBuilder,而且我看不到任何从Flurl掌握此方法的方法.

I'm currently using Polly and Flurl together, but I have a common retry policy that I have to add to every request. I notice that Polly allows you to set a default using AddPolicyHandler(...) but this requires an IHttpClientBuilder and I can't see any way of getting hold of this from Flurl.

我认为过载DefaultHttpClientFactory可能是解决方法,但这只能让我访问HttpClient,而不能访问IHttpClientBuilder.

I thought overloading DefaultHttpClientFactory might be the way to go, but that only gives me access to the HttpClient, not the IHttpClientBuilder.

我知道我可以制作自己的HttpClient并将其传递给Flurl,但我希望避免这种情况,因为我希望Flurl管理它们的生命周期.

I know I could make my own HttpClients and pass them into Flurl, but I'd rather avoid that if I can as I'd like Flurl to manage their lifecycle.

目前有一种方法可以做我想做的事吗?

Is there currently a way of doing what I want to do?

推荐答案

好问题. Flurl为您提供了所有必要的钩子.首先定义一个采用Polly策略的DelegatingHandler:

Great question. Flurl gives you all the necessary hooks to do this. First define a DelegatingHandler that takes a Polly policy:

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返回您的自定义处理程序:

Then create a custom IHttpClientFactory that returns your custom handler with the default handler as its 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注册:

Finally, on app startup, define your policy and register it with 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,因此使用这种方法不会陷入或重试这些响应和错误.上面示例中的策略陷阱HttpRequestExceptionHttpResponseMessage(具有非2XX状态代码),它们将起作用.

One important note is that this approach will not work with a policy that handles FlurlHttpException. That's because you're intercepting calls at the HttpMessageHandler level here. Flurl converts responses and errors to FlurlHttpExceptions higher up the stack, so those won't get trapped/retried with this approach. The policy in the example above traps HttpRequestException and HttpResponseMessage (with non-2XX status codes), which will work.

这篇关于使用Flurl设置默认的Polly策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-30 09:33