Dependency injection 为什么MVC4使用服务定位器反模式?

Dependency injection 为什么MVC4使用服务定位器反模式?,dependency-injection,ioc-container,asp.net-mvc-4,service-locator,Dependency Injection,Ioc Container,Asp.net Mvc 4,Service Locator,在阅读了马克·希曼的著作之后,我远离了反模式 阅读后,我看到: 通过DependencyResolver:Web API改进控制反转(IoC) 现在使用由MVC依赖项实现的服务定位器模式 解析程序,以获取许多不同设施的实例 因此,我感到好奇和困惑,为什么微软会在2012年使用服务定位器 这是一个您不应该关心的实现细节。重要的是,现在Web API使用DependencyResolver来解析许多不同设施的依赖关系,您将能够在任何时候插入这些设施时使用真正的依赖关系注入。因此,在代码中,您将使用真

在阅读了马克·希曼的著作之后,我远离了反模式

阅读后,我看到:

通过DependencyResolver:Web API改进控制反转(IoC) 现在使用由MVC依赖项实现的服务定位器模式 解析程序,以获取许多不同设施的实例


因此,我感到好奇和困惑,为什么微软会在2012年使用服务定位器

这是一个您不应该关心的实现细节。重要的是,现在Web API使用DependencyResolver来解析许多不同设施的依赖关系,您将能够在任何时候插入这些设施时使用真正的依赖关系注入。因此,在代码中,您将使用真正的依赖项注入。如果Microsoft没有使用依赖解析程序,那么当您想要实现某些自定义功能时,您必须在代码中使用它(作为服务定位器反模式),以便解析依赖关系。这对你来说是不好的。现在这对微软不利,但你不在乎他们

因此,我感到好奇和困惑,为什么微软会在2012年使用服务定位器


因为设计框架与使用框架设计应用程序不同。在设计可重用框架(如ASP.NET MVC)时,需要考虑一些不同的因素,而不仅仅是书本上写的内容。例如,在设计框架时,使用此框架的人将能够利用书中使用此框架编写的代码中的最佳实践。

正如Darin指出的那样,ASP.NET MVC 4是一个框架,并且与容器无关。这就是它以
idependencysolver
的形式提供服务定位器的原因。这允许任何人插入他们选择的容器

然而,我不认为这是一种反模式。这允许您使用自己选择的容器,但并不强制应用程序开发人员使用服务位置。如果框架强迫开发人员使用服务位置,那么我将称之为反模式。但是,构建ASP.NET MVC应用程序的开发人员可以通过构造函数注入、属性设置或服务位置自由使用DI。这是他们的选择

看看我或ASP.NETMVC团队发布的所有ASP.NETMVC依赖注入示例。在几乎所有情况下,他们都在使用构造函数注入。他们没有使用服务位置


事实上,大多数ASP.NET MVC源代码本身并不使用服务位置来检索依赖项。MVC调用遗留API等的服务定位器有几个关键位置。但仅此而已。

+1框架遵循的规则与应用程序不同。你想让框架容器不可知(如果想要使用框架的应用程序已经使用了不同的容器),你通常不想在这些应用程序上强制使用DI(因为他们可能根本不想使用DI),服务定位器是合适的。是的,框架不同于应用程序,但是完全可以不用服务定位器来编写框架。只要看看ASP.NETMVC1和2,甚至像WCF这样复杂的东西。ASP.NET MVC 3+中DependencyResolver的问题在于,它不仅仅是一个内部实现细节,而是被发布并吹捧为公共的“DI支持”。这里有一些要点:对于糟糕的开发人员的问题没有解决方案。这丝毫不会使我的观点无效。服务定位器也不是解决这个问题的良方……我尊重达林,但达林并没有写过一本我像马克·希曼那样崇拜的书。在这一点上,我需要做更多的研究,看到更多的答案。这似乎是合理的,我仍然想知道为什么我收到了Marcin Dobosz()的回复,他在给我的电子邮件中说Mark的书籍/和服务定位器是一种反模式,他说:“我没有读过这本书,所以我不熟悉为什么它是反模式的论点。你能澄清一下为什么你认为这是一个糟糕的设计吗?”为了澄清,我给我认识的为微软工作的Marcin发了一封电子邮件,很惊讶他从未听说服务定位器被称为反模式(这在互联网上很容易找到)我不是想把他扔到车下,但这是我认为Mark S所指的一个例子。你说:“看看我或ASP.NET MVC团队发布的所有ASP.NET MVC依赖注入示例。“你能提供一些你建议的链接吗?我的许多控制器都使用一些服务引用。他们得到一个对象,它被提供给一个模型对象(构造函数或方法),用来做一些工作来形成一个模型(viewModel,如果你愿意的话),这个模型被提供给一个视图。我想做IoC的主要原因是因为我的测试项目,我想能够提供其他东西,从ServiceReference实现iSeries,而不是从我的测试项目实际调用服务。我明白了为什么传统支持和DI过度使用的简单情况需要它。我只是想知道为什么他们没有使用System.IServiceProvider,而不是创建一个新的接口,然后需要为每个真正的DI容器编写新的包装器?