Logging 依赖注入和日志记录接口

Logging 依赖注入和日志记录接口,logging,dependency-injection,Logging,Dependency Injection,我想知道关于日志和日志框架以及依赖注入的一些最佳实践是什么。具体地说,如果我正在设计一个需要日志记录的类,那么我应该如何获得一个要记录的接口,以记住依赖项注入 依赖项注入似乎表明应该从外部(构造函数或属性设置器)注入外部依赖项,那么我应该在构造函数中获取一个ILog实例并在类中使用吗?我应该考虑记录一个可选的依赖项并在一个设置器中得到它吗?我是否因为允许日志接口发生变化而要求太多的灵活性?我是否应该对特定的日志接口进行硬依赖(例如,通过调用工厂方法创建静态ILog变量)?此工厂方法是否可以调用容

我想知道关于日志和日志框架以及依赖注入的一些最佳实践是什么。具体地说,如果我正在设计一个需要日志记录的类,那么我应该如何获得一个要记录的接口,以记住依赖项注入

依赖项注入似乎表明应该从外部(构造函数或属性设置器)注入外部依赖项,那么我应该在构造函数中获取一个ILog实例并在类中使用吗?我应该考虑记录一个可选的依赖项并在一个设置器中得到它吗?我是否因为允许日志接口发生变化而要求太多的灵活性?我是否应该对特定的日志接口进行硬依赖(例如,通过调用工厂方法创建静态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()
  {
  }
}

其他模式或方法可以做到这一点?外面的人在干什么?什么在工作,什么时候工作?

这不是一个完整的答案,但需要考虑的一点是,如果您通过类的构造函数注入ILog,那么您可以模拟该日志框架进行单元测试。其他想法。。。用于传递ILog的属性设置器意味着您不能记录来自构造函数的操作。此外,您还不确定您的实例是否有可用的ILog,这意味着您必须用有效ILog实例的测试来包装每个调用。

我会坚持注入它并使用接口。主要是为了方便测试。使测试消费对象时更容易替换模拟或存根

我将根据日志对消费类的重要性来决定是使用构造函数还是setter注入。若你们希望它是关键的,那个么我倾向于构造函数注入,若可选,那个么setter


我看不出使用工厂方法不能与容器一起工作的地方,但是,它会使测试消费者类依赖于此工厂方法的正确配置。

很好,您正在研究控制反转和依赖注入

但对于您的问题,您可能需要研究另一个概念:面向方面编程

在.NET中,有一些很好的框架可用于进行面向方面的编程,包括Castle、LinFu和Microsoft的策略注入应用程序块。事实上,一些控制反转容器中也有一些面向方面的特性


这些概念和工具有助于使诸如日志记录之类的问题在代码噪音方面占据后台,并使其自动处理。

我的建议是什么?将日志记录接口包装到您自己的日志记录接口中。我曾经依赖Log4Net,后来被烧掉了,因此不得不重构我的很多项目。

我会选择第二个或第三个选项,这取决于是否需要一个服务记录器。日志是面向方面编程的“你好,世界”。处理方法跟踪和异常是一回事,但积极事件日志记录又如何呢?当警告条件发生时,您需要记录它们,但不要中断实际的程序流。你能用方面来涵盖“所有(相关)”案例吗?@Karsten即使你注入了记录器,你仍然必须添加对每个将使用它的项目的引用,以便可以解析类或接口。使用回调的解决方案将100%的实现隔离到创建类的范围。