如何在依赖注入中使用log4net
我试图找出什么是正确的模式和使用log4net是依赖注入框架。
Log4Net使用ILog界面,但需要我打电话
LogManager.GetLogger(Reflection.MethodBase.GetCurrentMethod().DeclaringType)
在每个需要记录信息的类或方法中。 这似乎违背IoC原则,并且让我使用Log4Net。
我应该在某处放置另一个抽象层吗?
另外,我需要记录像当前用户名这样的自定义属性:
log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;
我如何封装这个,以便我不必每次都记得这样做,而仍然保持当前正在记录的方法。 我应该做这样的事情还是我完全错过了这个标志?
public static class Logger
{
public static void LogException(Type declaringType, string message, Exception ex)
{
log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;
ILog log = LogManager.GetLogger(declaringType);
log.Error(message, ex);
}
}
我想你没有看到这里的树林。 ILog和LogManager是一个轻量级的façade,几乎与Apache commons-logging相当于1:1,并且实际上并没有将代码耦合到log4net的其余部分。
<rant>
我也发现,几乎总是当有人创建一个围绕log4net的MyCompanyLogger包装时,他们很糟糕地错过了这一点,或者会丢失框架的重要和有用的功能,丢弃有用的信息,甚至使用简化的ILog界面失去性能增益,或以上全部。 换句话说, 包装log4net以避免耦合到它是一种反模式 。
</rant>
如果您觉得需要注入它,可以通过属性访问记录器实例以启用注入,但以旧式方式创建默认实例。
至于在每条日志消息中包含上下文状态,您需要添加一个全局属性,其ToString()
解析为您正在查找的内容。 例如,对于当前堆大小:
public class TotalMemoryProperty
{
public override string ToString()
{
return GC.GetTotalMemory(false).ToString();
}
}
然后在启动过程中插入它:
GlobalContext.Properties["TotalMemory"] = new TotalMemoryProperty();
我是如何创建自己的接口的,并且有一个类实现了使用Log4Net的接口,并注入了该类。 这样你就不会被绑定到Log4Net ......你可以为一个新的记录器创建另一个类并注入该类。
如果你真的关心有多个记录器,你总是可以声明一个全局记录器并为你的所有记录需求调用它。 缺点是你失去了识别日志发布类的内置功能,但你也可以在日志中注入自己的自定义消息来识别类。
这取决于你想要记录的强健程度。 您还可以简单地将记录器放在主类上,让所有未处理的异常冒泡到记录。
链接地址: http://www.djcxy.com/p/77707.html