我正在使用.Net Core v2.2。我需要将IHttpClientFactory传递到我的自定义LoggerProvider中。为了从ConfigureLogging中访问此服务,我可以这样做:
.ConfigureLogging((hostingContext, logBuilder) =>
{
var factory = logBuilder.Services.BuildServiceProvider().GetService(typeof(IHttpClientFactory)) as IHttpClientFactory;
logBuilder.AddProvider(new SlackLoggerProvider(factory));
})
我认为BuildServiceProvider()
最终会创建一组重复的服务。这个可以吗?它正在工作,但是我想知道这是否会影响IHttpClientFactory的生命周期或性能。有更好的方法吗?
答案 0 :(得分:1)
基于提供的代码的假设是
public class SlackLoggerProvider : ILoggerProvider {
private readonly IHttpClientFactory clientFactory;
public SlackLoggerProvider(IHttpClientFactory clientFactory) {
this.clientFactory = clientFactory;
}
//...
}
将必要的类型添加到服务集合中,以便框架可以在运行时对其进行解析
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) => {
services.AddHttpClient();
services.AddSingleton<ILoggerProvider, SlackLoggerProvider>();
});
添加的类型将在启动时提供给日志构建器。
在所示示例中,所有AddProvider
扩展名都将ILoggerProvider
派生实例作为单例添加到服务集合中。
public static ILoggingBuilder AddProvider(this ILoggingBuilder builder, ILoggerProvider provider)
{
builder.Services.AddSingleton(provider);
return builder;
}
您可以更进一步并添加扩展名
public static class SlackLoggerBuilderExtension {
public static ILoggingBuilder AddSlack(this ILoggingBuilder builder) {
builder.Services.AddHttpClient();
builder.Services.AddSingleton<ILoggerProvider, SlackLoggerProvider>();
//or
//builder.Services.AddSingleton<ILoggerProvider>(sp =>
// new SlackLoggerProvider(sp.GetRequiredService<IHttpClientFactory>())
//);
return builder;
}
}
确保添加了必需的依赖项。
二手
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostContext, logBuilder) => {
logBuilder.AddSlack();
});
答案 1 :(得分:0)
尝试一下:
.ConfigureLogging(builder =>
{
builder.Services.AddSingleton<ILoggerProvider, SlackLoggerProvider>();
})
然后您可以照常使用依赖项注入:
public class SlackLoggerProvider
{
private readonly IHttpClientFactory _clientFactory;
public SlackLoggerProvider(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
}
您只需要将IHttpClientFactory
添加到服务集合中即可
public void ConfigureServices(IServiceCollection services)
{
⋮
services.AddHttpClient();
⋮
}
更新:
我上面提供的答案确实导致了StackOverflowException
。我相信这是由于以下原因:
正在构建HttpClient的代码正在调用添加日志记录的代码,在这种情况下,它将再次调用正在构建HttpClient的代码...直到堆栈溢出。
因此,看来您在问题中使用的方法可能是完成您尝试做的事情的最佳方法,因为它可以解决所有问题,然后再将其发送到记录器。