简单的注入器和使用Log4net的日志抽象
为了尝试使用Log4net获得一个很好的日志抽象,我从这个SOpost中获取了抽象,并从这个SOpost中获取了适配器,并尝试让它们一起工作。
真正剩下要做的就是配置容器,这是我没有成功的部分。
我试过的配置是
public static class InfrastructureRegistry { public static void RegisterLoggingServices(this Container container) { container.RegisterConditional(typeof(ILog), c => LogManager.GetLogger( c.Consumer.ImplementationType).GetType(), Lifestyle.Scoped, c => true); container.RegisterPerWebRequest(); } }
从代码中可以看出,我想要一个特定的log4net记录器,它从注入它的类中获取Type。 虽然大多数日志记录都是在一个包罗万象的情况下完成的,但我希望在较低层进行一些日志记录,例如在表单validation失败时。
我使用该配置获得的ActivationException
是:
LogImpl类型的构造函数包含名为“logger”的参数,并键入未注册的ILogger。 请确保ILogger已注册,或更改LogImpl的构造函数。
不太确定从哪里开始,所以任何帮助将不胜感激。
编辑
对不起,我应该指出我正在尝试编写它,以便我只需要编写一次此配置。 以下工厂function有效,但我不想每次要注入记录器时手动添加更多配置:
container.RegisterPerWebRequest(() => LogManager.GetLogger(typeof(LoginController)));
您指向的示例适配器假定应用程序中的每个组件都有一个记录器,而您希望拥有一个“知道”其使用者的特定记录器,因此它可以将日志消息与原始类相关联。
虽然这在使用log4net和NLog等工具时似乎是一种非常普遍的做法,但根据我的经验,这个要求通常来自于在代码中太多地方完成日志记录的事实。 有关更多信息,请阅读此stackoverflow q / a 。
也就是说,如果要有条件地注册记录器,则必须将适配器更改为generics类; 这样你可以使注册有条件:
public class Log4netAdapter : ILogger { private static readonly log4net.ILog logger = LogManager.GetLogger(typeof(T)); public void Log(LogEntry entry) { if(entry.LoggingEventType == LoggingEventType.Information) logger.Info(entry.Message, entry.Exception); else if(entry.LoggingEventType == LoggingEventType.Warning) logger.Warn(entry.Message, entry.Exception); else if(entry.LoggingEventType == LoggingEventType.Error) logger.Error(entry.Message, entry.Exception); else logger.Fatal(entry.Message, entry.Exception); } }
使用此generics类,您可以执行以下条件/上下文注册:
container.RegisterConditional( typeof(ILogger), c => typeof(Log4netAdapter<>).MakeGenericType(c.Consumer.ImplementationType), Lifestyle.Singleton, c => true);