如果使用日志外观,在使用IoC/DI时是否应注入日志记录基础结构?

zam*_*6ak 35 .net logging dependency-injection inversion-of-control

我使用Autofac作为我的IoC和一切我已经阅读DI的话题提出使用"构造器注入"明确揭露类的依赖.不过,我也使用日志门面(Common.Logging)与log4net的,并已创建注入它的Autofac模块.现在,在我想要进行一些日志记录的每个类中,我都有额外的构造函数参数(参见示例#1)....

我想知道在使用日志门面时是否需要记录DI?我知道通过构造函数签名显式公开依赖是一个很好的架构. 但是在记录门面的情况下我相信以下是真的:

  • 我仍然可以随时"换出"日志框架
  • IMHO类并不真正依赖于Logger.如果未配置日志记录,则使用NullLogger.这几乎是"如果你需要的话就是它",而"除非你提供它,否则它将不起作用"这种交易......(参见样本#2)

那么,别人怎么想?注入伐木门面是否过度杀伤?关于这个主题有一些类似的问题,但更笼统地说(基础设施) - 我主要对记录....

// IoC "way"
public class MyController : BaseController
{
    private readonly ILog _logger;

    public MyController(ILog logger)
    {
        _logger = logger;
    }

    public IList<Customers> Get()
    {
        _logger.Debug("I am injected via constructor using some IoC!");
    }
}

// just use the logger "way"
public class MyController : BaseController
{
    private static readonly ILog Logger = LogManager.GetCurrentClassLogger();

    public IList<Customers> Get()
    {
        Logger.Debug("Done! I can use it!");
    }
}
Run Code Online (Sandbox Code Playgroud)

jga*_*fin 31

记录只是基础设施.注射它是过度的.我个人甚至不使用抽象层.我使用库直接提供的静态类.我的动机是,我不太可能在当前项目中切换日志库(但可能会切换到下一个项目).

但是,您在示例中使用控制器.你为什么需要登录?控制器只是视图和模型(业务逻辑)之间的适配器.应该没有必要登录.

您通常只登录包含业务逻辑的类,并在顶层执行以便能够记录未处理的异常.这些是调试的难点,因此需要进行日志记录.

必须在其他位置登录表示您需要重构以正确封装业务逻辑.

  • @Vijay:对不起,什么?如果找不到配置,则没有主要的日志记录库会影响您的应用程序.它只会停止记录.所以不,你是不对的. (3认同)
  • 我认为应该注入日志记录,因为它会对配置文件产生依赖性并妨碍自动化测试. (2认同)

Chr*_*ith 19

这可能是一个较旧的帖子,但我想插话.

日志系统的IOC过度杀伤的想法是短视的.

日志记录是一种机制,应用程序开发人员可以通过该机制与其他系统(事件日志,平面文件,数据库等)进行通信,而这些内容现在都是应用程序所依赖的外部资源.

如果我的单元测试代码现在被锁定到特定的记录器,我应该如何对组件的日志记录进行单元测试?分布式系统通常使用记录器来记录源,而不是文件系统上的平面文件.

向我注入记录器与注入数据库连接API或外部Web服务没有什么不同.它是应用程序所需的资源,因此应该注入,因此您可以测试组件对所述资源的使用情况模拟所述依赖性的能力,以独立于日志记录接收者来测试我的组件的输出,对于强单元测试.

并且鉴于IOC容器使得这样的注射成为孩子的游戏,在我看来,不使用IOC来注入记录器并不比这样做更有效.

  • in*some*cases logging*是一个真正的依赖.例如,某些数据库系统维护用于在发生故障时恢复数据的日志.如果没有此功能,数据库将无法再提供ACID保证,因此无法运行. (2认同)
  • 同意这一点.但是,我会问这是否真的记录了.日志记录不是数据库事务日志.数据库恢复不是软件的责任.数据库恢复是数据库的责任.日志记录是开发人员输出有关软件中业务操作状态的消息的一种方法,以及如何成功或不成功地处理此业务操作.如果我们可以接受这个作为日志记录的定义,那么我之前的观点就是这样. (2认同)
  • 这里的考虑是域与基础设施。如果日志出现在您的高级设计中,则是域问题。如果需要测试,因为它构成了接口的一部分。域代码应该被测试和注入 (2认同)

Ste*_*ven 6

现在,在我想做一些日志记录的每个类中,我都有额外的构造函数参数

如果您需要在系统中记录许多类,那么您的设计很有可能得到改进。要么记录太多(在太多地方),要么违反单一职责原则(或两者兼而有之),因为日志记录是一个横切关注点,并且您不应该用日志记录等横切关注点使您的类混乱。两者都会导致维护问题并增加应用程序的总拥有成本。

半年前我回答了一个(完全不同的)问题,我的答案适用于你的问题。请阅读这个