简单的注入器和使用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);