我想知道一些关于日志记录和日志记录框架以及依赖注入的最佳实践。具体来说,如果我正在设计一个需要记录方法的类,我应该如何设置一个接口来记录依赖注入?
依赖注入似乎表明外部依赖应该从外部注入(构造函数或属性设置器),所以我应该在构造函数中使用ILog实例并在类中使用吗?我应该考虑记录一个可选的依赖项并将其置于setter中吗?我是否通过允许更改日志记录接口来推动过多的灵活性,我是否应该对特定的日志记录接口进行硬依赖(例如通过调用工厂方法创建静态ILog变量)?这个工厂方法可以调用容器来获取ILog实现,还是会在初始化的静态变量和初始化的IoC容器之间产生初始化冲突?
我应该这样做:
public class MyService : ISomeService
{
private static readonly ILogger s_log =
LoggingFactory.GetLogger(typeof(MyService))
...
}
或者也许这样:
public class MyService : ISomeService
{
protected virtual ILogger Logger {get; private set;}
public MyService(ILogger logger, [other dependencies])
{
Logger = logger;
}
}
甚至是这样:
public class MyService : ISomeService
{
public virtual ILogger Logger {get; set;}
public MyService()
{
}
}
其他模式或方法可以做到这一点?那里的人在做什么?什么在起作用?什么时候起作用?
答案 0 :(得分:4)
你正在研究控制反转和依赖注入。
但是对于你的问题,还有一个你可能想要研究的概念:面向方面的编程。
在.NET中,有一些很好的框架可用于进行面向方面的编程,包括Castle,LinFu和Microsoft的Policy-Injection Application Block。事实上,一些控制反转容器也有一些面向方面的特性。
这些概念和工具有助于使日志记录等问题成为代码噪音的后台,并自动处理。
答案 1 :(得分:4)
我的建议?将日志记录界面包装到您自己的界面中。我曾经依赖Log4Net,因为它而被烧毁并不得不重构我的很多项目。
答案 2 :(得分:3)
这不是一个完整的答案,但一个考虑因素是如果你通过类的构造函数注入ILog,那么你可以模拟用于单元测试的日志框架。其他想法...用于传入ILog的属性设置器意味着您无法从构造函数中记录操作。此外,您不确定您的实例是否具有可用的ILog,这意味着您必须使用针对有效ILog实例的测试来包装每个调用。
答案 3 :(得分:0)
我会坚持注入并使用界面。主要是为了方便测试。在测试使用对象时,更容易替换模拟或存根。
我会根据日志对消费类的重要性使用构造函数或setter注入。如果你想让它变得至关重要,那么我倾向于构造函数注入,如果是可选的那么setter。
我没有看到使用工厂方法的地方无法使用容器,但是,它会根据此工厂方法的正确配置测试使用者类。