Fer*_*eia 8 c# logging common.logging
查看使用Common.Logging for .NET 的项目,我注意到有些类将logger实例声明为类静态成员.例如:
public class HelloJob : IJob
{
private static ILog _log = LogManager.GetLogger(typeof(HelloJob));
public HelloJob()
{
}
public virtual void Execute(IJobExecutionContext context)
{
_log.Info(string.Format("Hello World! - {0}", System.DateTime.Now.ToString("r")));
}
}
Run Code Online (Sandbox Code Playgroud)
在其他类中,记录器被声明为实例成员:
public class SimpleExample : IExample
{
public virtual void Run()
{
ILog log = LogManager.GetLogger(typeof (SimpleExample));
log.Info("------- Initializing ----------------------");
// etc
}
}
Run Code Online (Sandbox Code Playgroud)
是否有理由偏好一种方法或另一种方法?
在哪些情况下推荐每种方法?它与线程安全有关吗?
如果我刚刚宣布一个带有静态"记录器"成员的"Logger"类并且使用了整个项目(除了我在实践中会有一个全局变量的问题),这会是一个问题吗?
大多数记录器都是线程安全的,并且创建它们的实例在时间和内存方面都有很小的开销.因此,真正的问题需要从编程和可维护性的角度来看是有意义的.
一方面,由于记录器在概念上与您的类相关联,而不是与类的实例相关联,因此很多人更喜欢将其保持静态.这是一个非常有效的论点.例如,如果HelloWorldJob
扩展HelloJob
,我认为大多数人都希望代码编写的日志消息HelloJob
与HelloJob
类绑定,即使你有一个更具体的子类实例.能够从静态方法访问您的记录器也很好,如果它不在静态字段上,这是不可能的.
另一方面,没有理由让HelloJob负责获取自己的记录器实例.对于使用依赖注入(单元可测试性,附加可配置性和更简单的代码),有很多要说的.所以我个人建议让你的记录器由一个DI框架注入,在这种情况下需要在每个实例字段上引用它.
public class HelloJob : IJob
{
private readonly ILog _log;
public HelloJob(ILog log)
{
_log = log;
}
...
}
Run Code Online (Sandbox Code Playgroud)
您的DI框架可以根据它在运行时知道的详细信息设置记录器,或者您可以在单元测试中提供假的或模拟的记录器,以确保生成预期的日志消息.请注意,即使您指的是每个实例字段,您仍可以完全自由地使用每个类(甚至是单个)实例 - 这些只是不需要成为此类的一部分的详细信息关心.
归档时间: |
|
查看次数: |
4734 次 |
最近记录: |