2012-06-01 37 views
4

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

它只是看起来非常荒谬,所有类有10个参数ctors来通过DI来满足依赖关系。它的代码味道IMO。我可以理解诸如存储库或服务代理/连接器之类的东西,但不能记录日志。

+1

您可以将它们注入到全局应用程序上下文中。并从中消费。毕竟,容器是单身单身人士。 – DarthVader

+2

气味可能不是来自您的DI,而是来自您的10参数班,可能违反了“做一件事,做得很好”的理念。 – ken

+0

@ken这是我的观点,DI不是一种气味,它是10个参数。 – ILovePaperTowels

回答

2

这一切都取决于您在基础结构和代码的其余部分之间画线的位置。你认为数据库连接是基础设施吗?我不。

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

对于日志记录的特殊情况,我使用单例来获取记录器。

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

您可能会发现我的IoC introduction有用。

4

有几个选项。

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

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

然后就出现了这样一个问题,为什么有如此多的基础设施问题被注入组件?你所描述的被认为是交叉切割问题,通常这是通过AOP(面向方面​​编程)的一些处理来处理的,所以核心系统中没有很多重复。

+2

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

+0

我完全理解:)你的更好的选择,然后是#1与可选属性注入。我受不了服务定位器。感觉就像纯IoC的垫片一样。 –

1

关于日志记录 - 只需使用NLog(或您最喜爱的记录器)并完成它。除非你真的很奇怪,否则没有理由抽象和/或注入你的记录器。

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

关于安全 - 同样,我认为只有少数类应该是安全依赖的消费者。如果很多课程都关注安全性,则可能需要重新访问您的设计。

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