如何在依赖注入中使用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

上一篇: How to use log4net with Dependency Injection

下一篇: What's the difference between ng