阅读了Mark Seemann的《.NET中的依赖注入》之后,我远离了反模式服务定位器。
阅读了MVC 4版本发布说明后,我看到:
通过DependencyResolver改进了控制反转(IoC): Web API现在使用MVC的依赖解析器实现的服务定位器模式来获取许多不同设施的实例。
因此我很好奇并困惑为什么微软会在2012年使用服务定位器。
阅读了Mark Seemann的《.NET中的依赖注入》之后,我远离了反模式服务定位器。
阅读了MVC 4版本发布说明后,我看到:
通过DependencyResolver改进了控制反转(IoC): Web API现在使用MVC的依赖解析器实现的服务定位器模式来获取许多不同设施的实例。
因此我很好奇并困惑为什么微软会在2012年使用服务定位器。
这是一个实现细节,您不需要关心。重要的是,现在Web API使用DependencyResolver解决许多不同设施的依赖关系,您可以随时使用真正的依赖注入来插入这些设施。因此,在您的代码中,您将使用真正的依赖注入。如果Microsoft没有使用DependencyResolver
,那么你就必须在你的代码中使用它(作为服务定位器反模式),以便在想要实现一些自定义功能时解决依赖问题。这对于你来说会很糟糕。现在对于Microsoft来说很糟糕,但您不需要关心他们。
因此,我很好奇和困惑为什么Microsoft在2012年会使用服务定位器。
因为设计框架与使用框架设计应用程序是不同的。在设计可重复使用的框架(例如ASP.NET MVC)时,需要考虑一些不同的因素,而不仅仅是书上所写的内容。一些例子是设计框架的方式,使使用该框架的人能够在使用该框架的代码中采用书上写的最佳实践。
正如Darin所指出的,ASP.NET MVC 4是一个框架,它不依赖于容器。这就是为什么它提供了IDependencyResolver
形式的服务定位器。这使任何人都可以插入他们选择的容器。
然而,我不认为这是一种反模式。这允许您使用所选的容器,但它并不强制应用程序开发人员使用服务定位。如果框架强制开发人员使用服务定位,则我会称其为反模式。但构建ASP.NET MVC应用程序的开发人员可以通过构造函数注入、属性设置或服务定位来自由使用DI。这是他们的选择。
看看我或ASP.NET MVC团队发布的所有依赖注入的ASP.NET MVC示例。在几乎所有情况下,它们都使用构造函数注入。它们不使用服务定位。
实际上,大多数ASP.NET MVC源代码本身并不使用服务定位来检索依赖项。有一些关键位置,MVC会调用服务定位器来处理一些遗留API之类的事情。但仅此而已。