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

时间:2011-08-05 18:05:02

标签: asp.net-mvc-3 design-patterns language-agnostic dependency-injection

当谈到典型的构造函数依赖注入时,我很难理解看似明显的模式问题/限制。例如,假设我有一个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的缺点之一吗?我以前从未见过它,我觉得很好奇。

4 个答案:

答案 0 :(得分:6)

如果您有很多字段未被每个成员使用,则表示该类内聚力低。这是一个通用的编程概念 - 构造函数注入使其更加可见。这通常是一个很好的指标,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

答案 1 :(得分:5)

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

关于未使用的实例:无论是否使用DI,都很难创建一个在依赖类中完全利用实例的系统。只要你坚持Single Responsibility Principle,我不确定实现这一点非常重要。如果您发现您的类注入的服务太多,或者 ,那么这可能表示您的类做得太多,需要将其拆分为两个或更多个较小的类更专注的责任。

答案 2 :(得分:2)

不,您不会受到列出的限制。从.net 4开始,您可以使用Lazy(Of T),这样您就可以推迟实例化依赖项,直到需要为止。

不假设对象构造是便宜的,因此some DI容器支持Lazy(Of T)开箱即用。虽然Unity 2.0通过automatic factories支持延迟初始化,但在here上支持Lazy(Of T)作者的扩展名上有一篇很好的文章MSDN

答案 3 :(得分:0)

虽然你的控制器不是单身人士吗?这是在Java中执行它的常规方法。只创建了一个实例。如果操作的角色非常不同,您也可以将控制器拆分为多个控制器。

相关问题