【问题标题】:Calling DI Container directly in method code (MVC Actions)直接在方法代码中调用 DI Container (MVC Actions)
【发布时间】:2010-06-15 10:38:21
【问题描述】:

我正在玩 DI(使用 Unity)。我已经学会了如何进行构造函数和属性注入。我有一个通过 Global.asax 文件(MvcApplication 类)中的属性公开的静态容器。

我的控制器中需要许多不同的对象。通过构造函数注入这些似乎不太合适,部分原因是它们的数量很大,部分原因是它们仅在某些 Actions 方法中需要。

问题是,直接从 Action 方法中调用我的容器有什么问题吗?

public ActionResult Foo()
{
    IBar bar = (Bar)MvcApplication.Container.Resolve(IBar);
    // ... Bar uses a default constructor, I'm not actually doing any
    // injection here, I'm just telling my conatiner to give me Bar
    // when I ask for IBar so I can hide the existence of the concrete
    // Bar from my Controller.
}

这似乎是最简单和最有效的做事方式,但我从未见过以这种方式使用的示例。

这有什么问题吗?我在某种程度上错过了这个概念吗?

【问题讨论】:

    标签: design-patterns dependency-injection ioc-container


    【解决方案1】:

    是的,使用静态服务定位器有问题,因为it's an anti-pattern

    构造函数注入是你最好的选择。如果构造函数变得太大,则表明Controller违反了Single Responsibility Principle,您应该refactor to aggregate services

    【讨论】:

    • 谢谢马克,他们是非常好的博客文章。也许你是对的,我的控制器违反了 SRP。在 MVC 中似乎很容易陷入陷阱……与 Orders 相关的所有内容都应该进入 OrdersController,对吗?好吧,我想也许毕竟不是。但是你怎么知道你在定义责任时有足够的粒度呢?我的 Controller 的职责是在 Respository 和 Views 之间转发数据。我想你可能会说这是一个单一的责任。但它仍然需要六个辅助对象,具体取决于视图的哪一部分发生了变化。
    • 这种情况经常发生在控制器上,这不一定有什么问题。我的观点是,我们通常可以将那些原子依赖聚合成一些更高阶的抽象。这给了我们更多的层,但每一层在孤立时变得不那么复杂。
    猜你喜欢
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 2019-06-16
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 2020-09-17
    相关资源
    最近更新 更多