我的 .Net Core 应用程序中可以有两种不同的 ILogger 吗?
Can I have two different kinds of ILoggers in my .Net Core application?
我的应用程序有一部分只想记录到 EventLog。其余时间,我想登录到为我的 ILogger
设置的所有正常事件接收器。
我可以通过这样做在这些部分制作一个 ILogger:
var eventLogLoggerProvider = new Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider();
var eventLogger = eventLogLoggerProvider.CreateLogger("EventLogger");
eventLogger.LogWarning("We logged to the event log!");
但我觉得我应该通过依赖注入来完成。但是所有的例子只是展示了整个应用程序的一次设置。
有没有办法将 ASP.Net Core 3.1 应用程序配置为具有两种不同类型的 ILogger?(并允许将一种或另一种注入 class?)
您有多种选择。但是,其中 none 会特别好。 .NET Extensions DI 有点简单,而您的场景似乎相当高级。
直接使用EventLog
如果您非常喜欢在应用程序的特定位置使用 EventLog,那么直接使用它可能更有意义,因为 ILogger 抽象基本上与您的要求相反。
有了 ILogger
依赖,你说的是“给我一个记录器,不管是什么,我不在乎”。但你确实在乎。那么为什么不直接使用EventLog呢?或者为了可测试性将它隐藏在接口和适配器后面并注入它。
日志记录配置
或者,如果您通过 appsettings.json 配置日志记录,那么 EventLog 具有默认的 LogLevel = None 和 LogLevel = Information 或任何您喜欢的事件记录 assembly/namespace。其余记录器的事件记录区域具有 None LogLevel。例如:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"My.EventLogged.Assembly": "None"
},
"EventLog": {
"Default": "None",
"My.EventLogged.Assembly": "Information"
}
}
}
如果您将代码隔离到一个程序集或几个命名空间中,这会很好地工作,但是很容易添加另一个您只需要事件日志的地方而忘记这样配置它。
有关详细信息,请参阅
Logging in .NET Core and ASP.NET Core, Configuration section.
提供额外的上下文
如果您只需要事件日志记录的区域很容易分离,您可以提供一个具有单例生命周期的外观,这将创建一个单独的 IServiceCollection/IServicePrivoder,事件日志是该容器中唯一注册的 ILogger。
对事件记录代码的任何调用都应通过外观,该外观会使用内部 IServiceProvider 调用预期的实现。如果您需要从记录事件的代码调用应用程序的其余部分,则需要执行相反的操作。
这并不简单,但即使 ASP.NET Core 本身也会(或至少已经)这样做,以便在服务初始化尚未完成的启动期间提供日志记录。
但它肯定有一些令人惊讶的元素,并且可能会导致调试和诊断服务设置时出现一些令人头疼的问题。设置中也会存在口是心非。我相信这不是一个值得的方法。
使用不同的 IoC 容器
其他容器,例如 autofac 或 castle,可能能够根据使用名称的实例标识来解析多个服务(在本例中为 ILogger)。参见例如AutoFac FAQ: How do I pick service implementation by context.
但是,我无法就如何使用 ILogger 之类的东西执行此操作提供建议,因为日志记录注册相当复杂。
这些只是我可以想到的一些方向。我不认为对于您的要求有一个简单、规范的答案,您将不得不根据您的具体需求和情况进一步研究这些选项。
我的应用程序有一部分只想记录到 EventLog。其余时间,我想登录到为我的 ILogger
设置的所有正常事件接收器。
我可以通过这样做在这些部分制作一个 ILogger:
var eventLogLoggerProvider = new Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider();
var eventLogger = eventLogLoggerProvider.CreateLogger("EventLogger");
eventLogger.LogWarning("We logged to the event log!");
但我觉得我应该通过依赖注入来完成。但是所有的例子只是展示了整个应用程序的一次设置。
有没有办法将 ASP.Net Core 3.1 应用程序配置为具有两种不同类型的 ILogger?(并允许将一种或另一种注入 class?)
您有多种选择。但是,其中 none 会特别好。 .NET Extensions DI 有点简单,而您的场景似乎相当高级。
直接使用EventLog
如果您非常喜欢在应用程序的特定位置使用 EventLog,那么直接使用它可能更有意义,因为 ILogger 抽象基本上与您的要求相反。
有了 ILogger
依赖,你说的是“给我一个记录器,不管是什么,我不在乎”。但你确实在乎。那么为什么不直接使用EventLog呢?或者为了可测试性将它隐藏在接口和适配器后面并注入它。
日志记录配置
或者,如果您通过 appsettings.json 配置日志记录,那么 EventLog 具有默认的 LogLevel = None 和 LogLevel = Information 或任何您喜欢的事件记录 assembly/namespace。其余记录器的事件记录区域具有 None LogLevel。例如:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"My.EventLogged.Assembly": "None"
},
"EventLog": {
"Default": "None",
"My.EventLogged.Assembly": "Information"
}
}
}
如果您将代码隔离到一个程序集或几个命名空间中,这会很好地工作,但是很容易添加另一个您只需要事件日志的地方而忘记这样配置它。
有关详细信息,请参阅 Logging in .NET Core and ASP.NET Core, Configuration section.
提供额外的上下文
如果您只需要事件日志记录的区域很容易分离,您可以提供一个具有单例生命周期的外观,这将创建一个单独的 IServiceCollection/IServicePrivoder,事件日志是该容器中唯一注册的 ILogger。
对事件记录代码的任何调用都应通过外观,该外观会使用内部 IServiceProvider 调用预期的实现。如果您需要从记录事件的代码调用应用程序的其余部分,则需要执行相反的操作。
这并不简单,但即使 ASP.NET Core 本身也会(或至少已经)这样做,以便在服务初始化尚未完成的启动期间提供日志记录。
但它肯定有一些令人惊讶的元素,并且可能会导致调试和诊断服务设置时出现一些令人头疼的问题。设置中也会存在口是心非。我相信这不是一个值得的方法。
使用不同的 IoC 容器
其他容器,例如 autofac 或 castle,可能能够根据使用名称的实例标识来解析多个服务(在本例中为 ILogger)。参见例如AutoFac FAQ: How do I pick service implementation by context.
但是,我无法就如何使用 ILogger 之类的东西执行此操作提供建议,因为日志记录注册相当复杂。
这些只是我可以想到的一些方向。我不认为对于您的要求有一个简单、规范的答案,您将不得不根据您的具体需求和情况进一步研究这些选项。