当谈到典型的构造函数依赖注入时,我很难理解看似明显的模式问题/限制.例如,假设我有一个ASP.NET MVC3控制器,它看起来像:
Public Class MyController Inherits Controller Private ReadOnly mServiceA As IServiceA Private ReadOnly mServiceB As IServiceB Private ReadOnly mServiceC As IServiceC Public Sub New(serviceA As IServiceA,serviceB As IServiceB,serviceC As IServiceC) Me.mServiceA = serviceA Me.mServiceB = serviceB Me.mServiceC = serviceC End Sub Public Function ActionA() As ActionResult ' Do something with Me.mServiceA and Me.mServiceB End Function Public Function ActionB() As ActionResult ' Do something with Me.mServiceB and Me.mServiceC End Function End Class
我遇到困难的事情是,在任何给定时间,DI容器被要求实例化所有三个依赖项,这个控制器上的操作方法可能只需要一部分依赖项.
似乎假设对象构造是肮脏的,并且没有来自对象构造的副作用或者所有依赖性都被一致地利用.如果物体结构没有吱吱声或有副作用怎么办?例如,如果构建IServiceA涉及打开连接或分配其他重要资源,那么当调用ActionB时,这将完全浪费时间/资源.
如果这些操作方法使用服务位置模式(或其他类似模式),则永远不会有机会不必要地构造将不使用的对象实例,当然使用此模式会附加其他问题使其无法吸引人.
使用DI的规范构造函数注入接口模式是否基本上将开发人员锁定为一种“限制”,即依赖关系的实现必须是实例化的,或者实例必须被大量使用?我知道所有模式都有其优点和缺点,这只是DI的缺点之一吗?我以前从未见过它,我觉得好奇.
解决方法
如果你有很多字段没有被每个成员使用,这意味着类的凝聚力很低.这是一个通用的编程概念 – 构造函数注入使它更加明显.这通常是一个非常好的指标,表明
Single Responsibility Principle正在被侵犯.
如果是这种情况则重构(例如到Facade Services).
You don’t have to worry about performance when creating object graphs.
说到副作用,(DI)constructors should be simple and not have side effects.