39

我一直将Common Service Locator视为抽象 IoC 容器的一种方式,但我注意到有些人强烈反对这种类型。

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

4

4 回答 4

33

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

Common Service Locator 让您可以应对上述情况,而无需将给定的 IoC 强加给您的用户。

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

于 2009-08-13T09:08:56.820 回答
19

我注意到反对使用 CSL 的论据之一是错误的,因为开发人员认为这个库只能执行服务定位器模式。然而情况并非如此,因为它也很容易与依赖注入模式一起使用。

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

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

当您作为框架设计者依赖 CSL 时,用户将更难使用您的应用程序。用户必须配置一个 IoC 容器并将其连接到 CSL。但是,框架不可能像使用 .NET 配置系统时那样验证配置,因为它支持所有类型的验证。

于 2010-09-07T10:06:52.440 回答
9

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

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

于 2009-04-10T04:30:13.273 回答
0

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

于 2013-03-26T06:24:02.000 回答