我一直在寻找.net(c#)的日志框架,并决定在阅读stackoverflow上的一些问题/答案线程后给log4net一个机会.我看到人们一遍又一遍地提到他们使用log4net的包装类,我很想知道它会是什么样子.
我将我的代码拆分为不同的项目(数据访问/业务/ webservice/..).log4net包装器类怎么样?包装类是否需要包含在所有项目中?我应该将它作为一个单独的项目一起构建吗?
包装器应该是单件类吗?
本质上,您创建一个接口,然后创建该接口的具体实现,直接包装Log4net的类和方法.可以通过创建更具体的类来包装其他日志记录系统,这些类包装了这些系统的其他类和方法.最后使用工厂根据配置设置或代码更改行创建包装器的实例.(注意:使用诸如StructureMap的Inversion of Control容器,您可以更灵活 - 更复杂.)
public interface ILogger { void Debug(object message); bool IsDebugEnabled { get; } // continue for all methods like Error, Fatal ... } public class Log4NetWrapper : ILogger { private readonly log4net.ILog _logger; public Log4NetWrapper(Type type) { _logger = log4net.LogManager.GetLogger(type); } public void Debug(object message) { _logger.Debug(message); } public bool IsDebugEnabled { get { return _logger.IsDebugEnabled; } } // complete ILogger interface implementation } public static class LogManager { public static ILogger GetLogger(Type type) { // if configuration file says log4net... return new Log4NetWrapper(type); // if it says Joe's Logger... // return new JoesLoggerWrapper(type); } }
以及在类中使用此代码的示例(声明为静态只读字段):
private static readonly ILogger _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
使用以下方法可以获得相同的性能友好效果:
private static readonly ILogger _logger = LogManager.GetLogger(typeof(YourTypeName));
前一个例子被认为更易于维护.
您不希望创建Singleton来处理所有日志记录,因为Log4Net记录了调用类型; 让每种类型使用自己的记录器而不仅仅是在日志文件中看到报告所有消息的单一类型,它更加清晰和有用.
因为您的实现应该是可以重复使用的(组织中的其他项目),您可以将其设置为自己的程序集,或者理想地将其包含在您自己的个人/组织的框架/实用程序程序集中.不要在每个业务/数据/ UI程序集中单独重新声明类,这是不可维护的.
假设你正在使用上面的cfeduke的答案,你也可以添加一个过载LogManager
:
public static ILogger GetLogger() { var stack = new StackTrace(); var frame = stack.GetFrame(1); return new Log4NetWrapper(frame.GetMethod().DeclaringType); }
在您的代码中,您现在可以使用:
private static readonly ILogger _logger = LogManager.GetLogger();
而不是以下任何一个:
private static readonly ILogger _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILogger _logger = LogManager.GetLogger(typeof(YourTypeName));
这实际上相当于第一种替代方案(即使用的替代方案MethodBase.GetCurrentMethod().DeclaringType
),只是稍微简单一些.
您计划在编写log4net的包装器时有什么好处.我建议在编写包装器之前先熟悉log4net类.cfeduke在他关于如何编写所述包装器的答案中是正确的,但除非你需要在他的示例中添加实际功能,否则包装器只会成功地减慢日志记录过程并增加未来维护者的复杂性.当.Net中可用的重构工具使这些更改变得非常容易时尤其如此.