Ter*_*rje 10 c# logging dependency-injection polly asp.net-core-2.1
或者:如何从静态方法记录。
从https://github.com/App-vNext/Polly你可以看到像这样的例子,其中记录器神奇地可用:
Policy
.Timeout(30, onTimeout: (context, timespan, task) =>
{
logger.Warn($"{context.PolicyKey} at {context.ExecutionKey}: execution timed out after {timespan.TotalSeconds} seconds.");
});
Run Code Online (Sandbox Code Playgroud)
在我的代码中,我使用IHttpClientFactorydotnet core 2.1 中的新模式,并将其添加到我的 Startup.csConfigureServices方法中:
services.AddHttpClient<IMySuperHttpClient, MySuperHttpClient>()
.AddPolicyHandler(MySuperHttpClient.GetRetryPolicy())
.AddPolicyHandler(MySuperHttpClient.GetCircuitBreakerPolicy());
Run Code Online (Sandbox Code Playgroud)
静态且GetRetryPolicy看起来像这样:
internal static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(
retryCount: 4,
sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
onRetry: OnRetry);
}
Run Code Online (Sandbox Code Playgroud)
其中OnRetry方法也必须是静态的:
private static void OnRetry(DelegateResult<HttpResponseMessage> delegateResult, TimeSpan timespan, Context context)
{
// var logger = ??
// logger.LogWarning($"API call failed blah blah.");
}
Run Code Online (Sandbox Code Playgroud)
ILoggerFactory如果可能的话,如何访问这里?
正如山地旅行者的评论中所述,有多种方法可以解决该问题:
Context之间传递任意对象Execute(Async)onRetry(Async)AddPolicyHandler前一种解决方案需要显式调用Execute/ExecuteAsync才能提供Context封装ILogger实例的对象。对于命名/类型化 Http 客户端,此路由不是一个可行的选择,因为您HttpClient用PolicyHttpMessageHandler. Execute(Async)因此,代表您调用 Handler 的不是您的代码。
后一个解决方案提供对 的访问,IServiceProvider您可以从中检索任何已注册的服务。(它还将请求作为参数传递。)
services.AddHttpClient<IMySuperHttpClient, MySuperHttpClient>()
.AddPolicyHandler((provider, _) => MySuperHttpClient.GetRetryPolicy(provider))
Run Code Online (Sandbox Code Playgroud)
因此,您需要做的就是将其IServiceProvider向下传递给您的 OnRetry方法
internal static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(IServiceProvider provider)
=> HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == HttpStatusCode.NotFound)
.WaitAndRetryAsync(4,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
OnRetry(provider));
}
Run Code Online (Sandbox Code Playgroud)
代表期望的WaitAndRetryAsync地方不存在这种过载。我们需要引入一个像这样的辅助方法:onRetryIServiceProvider
private static Action<DelegateResult<HttpResponseMessage>, TimeSpan> OnRetry(IServiceProvider provider)
=> (dr, ts) => OnRetry(dr, ts, provider);
private static void OnRetry(DelegateResult<HttpResponseMessage> delegateResult, TimeSpan timespan, IServiceProvider provider)
{
// var logger = ??
// logger.LogWarning($"API call failed blah blah.");
}
Run Code Online (Sandbox Code Playgroud)
OnRetry接收IServiceProvider并返回一个Action<DelegateResult<HttpResponseMessage>, TimeSpan>
WaitAndRetryAsync委托onRetryOnRetry与你的相同,我刚刚将你的上下文参数替换为提供程序因此,基本上第一个充当和第二个OnRetry之间的适配器以通过.WaitAndRetryAsyncOnRetryprovider
| 归档时间: |
|
| 查看次数: |
5701 次 |
| 最近记录: |