IOC容器类型分辨率和注入位置

时间:2010-07-29 19:42:07

标签: dependency-injection

最佳做法是在域模型的边缘解析和注入具体类型,然后通过域下载这些类型?例如,让容器将具体类型注入Web应用程序中的MVC控制器构造函数,或基于服务的应用程序中的服务端点?

我对容器对象图形连线的理解有点松懈。

在域中执行等效的Container.Resolve()是否合适?

2 个答案:

答案 0 :(得分:6)

DI实际上只是达到目的的手段:松散耦合。这是一种通过将接口(或基类)注入消费者来实现松散耦合的方法,这样您就可以彼此独立地改变它们。

作为一般规则,通过注入具体类型获得的不多。你不能用另一种类型交换类型,因此DI的主要优点就会丢失。

您可能会认为这意味着您只需从消费者中创建具体实例,但更好的选择是从这些类型中提取接口(然后注入它们)

并且没有:永远不适合从域模型中提取容器。那是Service Locator anti-pattern好莱坞原则也适用于此:

  

不要打电话给容器;它会打电话给你

(也就是说,即使是具体的类型,注入它也有一些辅助的好处。如果它是非密封的并且有一个或多个虚拟成员,你仍然可以覆盖它的一些行为,即使它是密封的,如果你注入它,你仍然可以控制它的生命周期 - 例如,你可以在多个消费者之间共享相同的实例。但是,这些好处纯粹是次要的,通常不是我们决定注入任何东西的主要原因。)


另一个问题(以及您似乎实际要问的问题)是注入服务是否适合将其传递给其他服务。不,不是,因为它会违反单一责任原则并导致Constructor Over-Injection

最好将细粒度服务包含在更粗粒度的服务中。我将这些称为Aggregate Services抽象外墙。虽然这些本身具有依赖性(如您提到的服务端点),但这些将是实现细节。从顶级消费者的角度来看,它们并不存在。

这不仅可以很好地解决构造函数中过多依赖项的问题,还可以帮助您在应用程序层之间实现更好的隔离

答案 1 :(得分:2)

查看KrzysztofKoźmic关于这个主题的blog post(s) - 我认为他对此有一些很好的看法,他们几乎总结了当前的“最佳实践”。