DI模式是否限制了昂贵的对象创建以及不常使用的依赖关系?

cki*_*tel 8 language-agnostic design-patterns dependency-injection asp.net-mvc-3

当谈到典型的构造函数依赖注入时,我很难理解看似明显的模式问题/限制.例如,假设我有一个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
Run Code Online (Sandbox Code Playgroud)

我遇到困难的事情是,在任何给定时间,DI容器被要求实例化所有三个依赖项,这个控制器上的操作方法可能只需要一部分依赖项.

似乎假设对象构造是肮脏的,并且没有来自对象构造的副作用或者所有依赖性都被一致地利用.如果物体结构没有吱吱声或有副作用怎么办?例如,如果构建IServiceA涉及打开连接或分配其他重要资源,那么在ActionB调用时将完全浪费时间/资源.

如果这些操作方法使用服务位置模式(或其他类似模式),则永远不会有机会不必要地构造将不使用的对象实例,当然使用此模式会附加其他问题使其不具吸引力.

使用DI 的规范构造函数注入+接口模式是否基本上将开发人员锁定为一种"限制",即依赖项的实现必须是实例化的,或者实例必须被大量使用?我知道所有模式都有其优点和缺点,这只是DI的缺点之一吗?我以前从未见过它,我觉得好奇.

Mar*_*ann 6

如果你有很多字段没有被每个成员使用,这意味着类的凝聚力很低.这是一个通用的编程概念 - 构造函数注入使它更加明显.这通常是违反单一责任原则的一个很好的指标.

如果是这种情况则重构(例如Facade Services).

创建对象图时,您不必担心性能.

当涉及副作用时,(DI)构建者应该简单并且没有副作用.


Phi*_*ler 5

一般来说,对象构造不应有重大成本或副作用.这是一个我认为适用于大多数(并非所有)对象的一般性陈述,但对于通过DI注入的服务尤其如此.换句话说,构建服务类会自动进行数据库/服务调用,或者以一种副作用(至少)代码味道的方式更改系统状态.

关于未使用的实例:无论是否使用DI,都很难创建一个在依赖类中完美利用实例的系统.只要您遵守单一责任原则,我不确定实现这一点非常重要.如果您发现您的班级注入的服务太多,或者利用率确实不均衡,则可能表明您的班级做得太多,需要分成两个或更多的小班,责任更集中.