我正在使用Autofac作为我的IoC,并且从我读过的关于DI主题的所有内容中使用“构造函数注入”来显式地暴露类依赖... 但是,我也在使用日志外观(Common.Logging)和Log4Net,并创建了Autofac模块来注入它。 现在,在我想要进行一些日志记录的每个类中,我都有额外的构造函数参数(参见示例#1)....
我想知道在使用日志门面时是否需要记录DI? 我知道通过构造函数签名显式公开依赖是一个很好的架构。 但如果是登录外观我相信以下是真的:
那么,别人怎么想?注入伐木门面是否过度杀伤? 关于这个主题有一些similar questions但是更笼统地说(infrastructure) - 我主要对记录感兴趣....
// 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!");
}
}
答案 0 :(得分:29)
记录只是基础设施。注射它是矫枉过正的。我个人甚至不使用抽象层。我使用库直接提供的静态类。我的动机是,我不太可能在当前项目中切换日志库(但可能会切换到下一个项目)。
但是,您在示例中使用的是控制器。你为什么需要登录?控制器只是视图和模型(业务逻辑)之间的适配器。应该没有必要登录。
您通常只登录包含业务逻辑的类,并在顶层执行以便能够记录未处理的异常。这些是调试的难点,因此也是需要记录的地方。
必须在其他地方登录表示您需要重构以正确封装您的业务逻辑。
答案 1 :(得分:18)
这可能是一篇较老的帖子,但我想加入。
日志记录系统的IOC过度使用的想法是短视的。
日志记录是一种机制,应用程序开发人员可以通过该机制与其他系统(事件日志,平面文件,数据库等)进行通信,并且这些内容现在都是应用程序所依赖的外部资源。
如果我的单元测试代码现在已锁定到特定记录器,我应该如何对组件的日志记录进行单元测试?分布式系统通常使用记录器来记录源,而不是文件系统上的平面文件。
向我注入记录器与注入数据库连接API或外部Web服务没有什么不同。它是应用程序所需的资源,因此应该注入,因此您可以测试组件对所述资源的使用情况模拟所述依赖性的能力,以独立于日志记录接收者来测试我的组件的输出,对于强单元测试。
鉴于IOC容器使得这样的注射成为孩子的游戏,在我看来,不使用IOC来注入记录器并不是一种有效的方法。
答案 2 :(得分:4)
现在,在我想要做一些日志记录的每个班级中,我都有额外的 构造函数参数
如果您需要在系统中记录许多类,那么您的设计就会出现问题。要么你记录太多,要么你违反了单一责任原则,因为记录是一个贯穿各领域的问题,你不应该把你的课程弄得像日志这样的跨界问题。
半年前我回答了一个(完全不同的)问题,我的回答适用于你的问题。请阅读this。
答案 3 :(得分:2)
我个人认为这太过分了。
理想情况下,日志记录的开销非常低,因此每个类的单个静态记录器实例似乎是更好的解决方案。保持低开销可以促进使用调试级别的日志记录进行检测。
答案 4 :(得分:0)
在许多应用程序中,由于需要在整个应用程序的体系结构中进行日志记录,因此将日志注入到各处都会使代码变得混乱和复杂。只要您的Logger
具有某种Logger
机制,并为运行环境附加日志服务,就可以静态引用Attach(ILoggerService)
对象。然后,您的静态Logger
将它们存储在一个集合中,以便在执行记录命令时使用。
在运行时引导应用程序时,请附加应用程序所需的日志记录目标(文件,数据库,Web服务等)。
执行自动测试时,可以通过不附加任何内容来选择不使用日志记录(默认情况下)。如果要分析被测系统的日志记录,请在设置测试时附加自己的ILoggerService
实例/替代/模拟。
诸如此类的静态Logger
应该具有最小的性能问题,并且不会产生意想不到的后果,同时避免了依赖注入的需要,从而避免了代码混乱。
必须指出,您不应该对体系结构中的每个对象都采用这种静态对象方法。日志记录是一个特例。通常,在代码库中使用静态对象会使维护和测试变得困难,应该避免。