在asp.net核心1.1中,我可以将IServiceProvider注入到记录器提供程序中并在调用CreateLogger
时解析我的记录器,但在asp.net core 2.0中它都已更改
我的ILogger实现需要注入依赖项。 我怎样才能做到这一点?
答案 0 :(得分:3)
ASP.NET核心提供了用自定义替换内置DI容器的可能性(有关详细信息,请参阅this文章)。您可以使用这种可能性来获取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;
}
// ...
}
答案 1 :(得分:0)
从各个地方开始需要依赖项开始
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;
}
}
记录器提供程序是被称为 AFTER 服务的部分,当您处理业务代码并需要记录内容时便会建立这些服务。
因此,在应用程序上下文中,将构建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!);
}
在我的示例中,它将打印消息到控制台(如果有)以及带有我们注入的Dependency的CustomLogger。如果您注册更多..它将去所有的人
答案 2 :(得分:0)
如果要在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();