4

对于记录器、安全性、配置等基础设施项目,这些东西应该真正注入到需要它们的每个类中,还是应该注入到服务定位器中,然后这些类可以使用服务定位器来解决依赖关系(或一些其他机制)?

所有类都有 10 个参数 ctor 来通过 DI 满足依赖关系,这看起来真的很荒谬。它是一种代码气味 IMO。我能理解诸如存储库或服务代理/连接器之类的东西,但不能理解日志。

4

3 回答 3

4

有几个选择。

  1. 使用属性注入并在 ctor 中设置默认值。例如

    class foo 
    {
        public ILogger Logger {get;set;}
    
        public foo()
        {
           Logger = NullLogger.Instance;
        }
    }
    
  2. 使用 AOP 类型的方法。使用动态代理,您可以使用日志记录语句包装公共调用,但日志记录实际上从未注入到组件本身中。有关此方法的更多想法,请参阅Castle.DynamicProxy或自定义 .Net 属性。

那么问题来了,为什么要向组件中注入如此多的基础设施问题?您所描述的被认为是横切关注点,通常这是通过一些 AOP(面向方面​​的编程)来处理的,因此核心系统中没有很多重复。

于 2012-06-01T16:26:11.660 回答
2

这完全取决于您在基础设施和其余代码之间划清界限的位置。你认为数据库连接是基础设施吗?我不。

属性注入是一种代码味道,因为它隐藏了依赖关系,并且在构造函数完成时没有正确初始化类。只用它来解决循环依赖。

对于非常具体的记录情况,我确实使用单例来获取记录器。

通常我会同意你对 AOP 的看法,但我不是运行时 AOP 框架的粉丝,而且团队不了解 AOP 概念。他们几乎不了解 IoC 概念

您可能会发现我的IoC 介绍很有用。

于 2012-06-04T14:09:40.960 回答
1

关于日志记录 - 只需使用 NLog(或您最喜欢的记录器)并完成它。除非您处于一个非常奇怪的场景中,否则没有理由抽象和/或注入您的记录器。

关于配置 - 只有少数类应该是配置的消费者,所以这不应该导致构造函数膨胀。有关配置和 DI 的详细讨论,另请参阅此问题

关于安全性 - 同样,我认为只有少数类应该是安全依赖项的消费者。如果许多类都与安全有关,您可能需要重新审视您的设计。

一般来说 - 如果一个类有太多的构造函数参数,可能是因为它做的太多了,不管依赖项是否是基础设施。

于 2012-06-01T19:18:47.943 回答