我目前同时使用Polly和Flurl,但我有一个通用的重试策略,我必须将其添加到每个请求中。我注意到Polly允许您使用AddPolicyHandler(...)设置默认值但这需要一个IHttpClientBuilder,我看不到任何从Flurl获取它的方法。
我认为重载DefaultHttpClientFactory可能是可行的方法,但这只能让我访问HttpClient,而不是IHttpClientBuilder。
我知道我可以制作自己的HttpClients并将它们传递到Flurl中,但如果我可以的话,我宁愿避免这种情况,因为我希望Flurl管理它们的生命周期。
目前有没有办法做我想做的事?
发布于 2018-09-12 04:48:14
问得好。Flurl为您提供了完成此操作所需的所有挂钩。首先定义一个采用Polly策略的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);
}
}
然后创建一个以默认处理程序作为其InnerHandler
返回自定义处理程序的自定义IHttpClientFactory
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
,因此这种方法不会捕获/重试这些响应和错误。上例中的策略会捕获HttpRequestException
和HttpResponseMessage
(具有非2XX状态代码),这将起作用。
https://stackoverflow.com/questions/52272374
复制相似问题