您什么时候使用公共服务定位器?

时间:2009-04-09 19:55:37

标签: c# dependency-injection inversion-of-control service-locator common-service-locator

我一直在考虑Common Service Locator作为抽象我的IoC容器的方法,但我注意到有些人强烈反对这种类型。

人们建议永远不要使用它吗?一直在使用它?或者有时使用它? 如果有时候,那么在什么情况下你会使用它以及你不会使用它的情况。

4 个答案:

答案 0 :(得分:32)

想象一下,您正在编写供第三方开发人员使用的库代码。您的代码需要能够创建这些开发人员提供的服务对象。但是,您不知道每个呼叫者将使用哪个IoC容器。

通用服务定位器可让您在不强制用户使用特定IoC的情况下处理上述问题。

在你的库中你可能希望在IoC中注册你自己的类,现在它变得更加困难,因为你需要为自己选择一个不会妨碍你的调用者的IoC。

答案 1 :(得分:19)

我注意到反对使用CSL的一个论点是假的,因为开发人员认为这个库只能执行Service Locator模式。但事实并非如此,因为它也很容易与依赖注入模式一起使用。

但是,CSL库是专为需要允许用户注册依赖项的框架设计者而设计的。因为库将直接调用CSL,从框架的角度来看,我们正在谈论SL模式,因此它的名称。

作为框架设计师,依赖CSL不应该掉以轻心。为了您的框架的可用性,拥有自己的DI机制通常要好得多。一种非常常见的机制是在配置文件中设置依赖项。这种模式在整个.NET框架中使用。几乎每个依赖都可以替换为另一个。 .NET提供程序模式构建于此之上。

当您作为框架设计人员依赖CSL时,用户将更难以使用您的应用程序。用户必须配置IoC容器并将其连接到CSL。但是,框架无法像使用.NET配置系统那样验证配置,而.NET配置系统就是其中的所有验证支持。

答案 2 :(得分:9)

我最近对服务定位器概念做了一些阅读。这是一种帮助减少耦合的方法,但需要代码耦合到定位器 - 而不是支持定位器的容器,而是定位器本身。这是一种权衡,但在适当的情况下可能是有益的。

一种可能有用的情况是当你有不使用DI的代码时,例如遗留代码 - 我现在就在这艘船上。通过SL拉入所需的对象,而不是直接创建它们,允许添加一些抽象。我认为它是SL和DI / IoC之间的中间步骤。

答案 3 :(得分:0)

如果你有需要服务的库代码,并且这个代码可以托管在更大的框架/运行时的上下文中,那么框架/运行时需要提供一种机制,你可以在启动时运行一些自定义代码,其中您可以初始化容器并注册依赖项。 CSL可能存在问题的一个很好的例子是在MSCRM的上下文中使用它。您可以通过注册MSCRM框架在某些事件上执行的插件来执行自定义业务逻辑。您遇到的问题是在哪里运行注册逻辑,因为没有“启动”事件可以订阅以设置您的DI容器。即使您可以以某种方式设置您的DI,您也需要将CSL和DI库放在GAC中,因为这是从插件中调出第三方代码的唯一方法(还有一个项目要添加到您的部署清单中)。 在诸如此类的场景中,最好将依赖项作为构造函数参数,调用代码可以在其认为合适时进行初始化(通过构造函数注入或手动“新建”相应的接口实现)。