[英]Serilog DI in ASP.NET Core, which ILogger interface to inject?
[英]How can I inject dependencies into a custom ILogger in asp.net core 2.0?
在 asp.net core 1.1 中,我可以將 IServiceProvider 注入記錄器提供程序並在調用CreateLogger
時解析我的記錄器,但在 asp.net core 2.0 中這一切都發生了變化
我的 ILogger 實現需要注入依賴項。 我怎樣才能做到這一點?
ASP.NET核心提供了可能性,以取代內置自定義一個DI容器(見本文章詳細信息)。 您可以使用這種可能性來獲取IServiceProvider
實例,以便在仍然使用標准 .Net 核心 DI 容器的同時進行記錄引導。
為此,您應該將Startup.ConfigureServices(IServiceCollection services)
方法的返回值從 void 更改為IServiceProvider
。 您可以使用這種可能性在 ConfigureServices 中構建 IServiceProvider 的實例,將其用於記錄引導,然后從該方法返回。
示例代碼:
public interface ISomeDependency
{
}
public class SomeDependency : ISomeDependency
{
}
public class CustomLogger : ILogger
{
public CustomLogger(ISomeDependency dependency)
{
}
// ...
}
public class CustomLoggerProvider : ILoggerProvider
{
private readonly IServiceProvider serviceProvider;
public CustomLoggerProvider(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public ILogger CreateLogger(string categoryName)
{
return serviceProvider.GetRequiredService<ILogger>();
}
// ...
}
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc();
return ConfigureLogging(services);
}
private IServiceProvider ConfigureLogging(IServiceCollection services)
{
services.AddTransient<ISomeDependency, SomeDependency>();
services.AddSingleton<ILogger, CustomLogger>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
var loggerFactory = new LoggerFactory();
loggerFactory.AddProvider(new CustomLoggerProvider(serviceProvider));
return serviceProvider;
}
// ...
}
如果您在 program.cs 中配置日志記錄,您可以創建一個函數來配置日志記錄並獲取日志記錄提供程序的實例,如下所示:
private static void ConfigureApplicationLogging(WebHostBuilderContext context, ILoggingBuilder loggingBuilder)
{
loggingBuilder.AddConfiguration(context.Configuration.GetSection("Logging"));
loggingBuilder.AddDebug();
loggingBuilder.AddConsole();
var serviceProvider = loggingBuilder.Services.BuildServiceProvider();
loggingBuilder.AddProvider(new DoxErrorLoggerProvider(serviceProvider, null));
}
然后在 BuildWebHost 中,您將按如下方式配置日志記錄:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging(ConfigureApplicationLogging)
.UseNLog()
.UseStartup<Startup>()
.Build();
從你在不同地方需要的那個依賴開始
public class SomeDependency : ISomeDependency
{
}
一個擴展文件,因此我們可以根據 MSDN 在 ServiceCollection 上配置日志記錄 您可以在各種來源上找到相當標准的東西
public static class ApplicationLoggerFactoryExtensions
{
public static ILoggingBuilder CustomLogger(this ILoggingBuilder builder)
{
builder.Services.AddSingleton<ILoggerProvider, CustomLoggerProvider>();
//Be careful here. Singleton may not be OK for multi tenant applications - You can try and use Transient instead.
return builder;
}
}
記錄器提供程序是在您處理業務代碼並需要記錄內容時構建服務后調用的部分。
因此,在應用程序的上下文中,DI 在此處構建並可用。 現在為什么ILoggerProvider
現在存在可能是有道理的。
public class CustomLoggerProvider : ILoggerProvider
{
private ISomeDependency someDependency;
public CustomLoggerProvider(ISomeDependency someDependency)
{
this.someDependency = someDependency;
}
public ILogger CreateLogger(string categoryName)
{
return new CustomeLogger(someDependency);
}
}
具體的自定義記錄器非常簡單的東西
public class CustomLogger : ILogger
{
public CustomLogger(ISomeDependency dependency)
{
}
}
並且在您配置 ServiceCollection 的地方.. 就像在 Startup.cs 中的 OP 問題一樣
private void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISomeDependency, SomeDependency>();
//services.AddSingleton<ILogger, CustomLogger>(); <== NO
var loggerFactory = new LoggerFactory(); //??? newer DotNet gives you LoggerFactory in startup this may be unnecessary.
//Add some console printer
services.AddLogging(configure => configure.AddConsole())
.Configure<LoggerFilterOptions>(options => options.MinLevel = LogLevel.Trace);
//Add our custom logger
services.AddLogging(configure => configure.CustomLogger()); // <== our extension helping out!
}
✘ 不要 - 不要在您的服務中添加任何 ILogger
LoggerFactory
和LoggerProvider
配置的重點是簡化使用ILogger
public MyBusinessService(ILogger<BusinessServiceClass> log)
{
log.Information("Please tell all registered loggers I am logging!);
}
在我的示例中,它將向控制台打印消息(如果可用)以及接受我們注入的依賴項的 CustomLogger。 如果你注冊更多..它會去所有人
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.