服务定位器 - 值得吗?

Pet*_*eGO 6 .net design-patterns service-locator

我们有一个大型解决方案(> 100个项目),几乎每种类型都使用服务定位器(示例1)或我们自己的类型字典(示例2)进行实例化.

例如,我们有:

IQuote quote = Registry.Resolve<IQuote>(); 
Run Code Online (Sandbox Code Playgroud)

要么

IQuote quote = Registry.Find<IQuote>(args);
Run Code Online (Sandbox Code Playgroud)

第二个示例转到配置文件,以查找使用反射实例化的具体对象.

通过代码后,它会让生活变得更加困难 - 因为不清楚使用的具体类型是什么 - 因此我们必须多次检查映射,因为我们正在尝试学习代码的一部分.使用以上作为示例按F12:quote.DoSomething()将带您进入接口定义.

它实现起来有点困难 - 我们需要一个接口+具体的类+配置映射,当替代只有一个类时.

想一想 - 我不知道有什么东西曾被"换掉"换成另一种类型 - 所以虽然我们已经实现了IoC但我们还没有使用它,或者至少 - 很少.

那么 - 它真的值得吗?我们是否错误/太多地实施了它?我误会了什么吗?

Roo*_*ian 5

你们正在使用的是一个被认为是反模式的服务定位器,因为:

  1. 所有单元测试都必须使用服务定位器(DI 不涉及DI 容器
  2. 您将整个架构耦合到服务定位器(在DI 中,只有Composition Root使用DI Container
  3. 您无法立即看到组件的依赖关系(使用DI构造函数注入
  4. 您的单元测试变得更加复杂,因为您必须关心您的配置,以免其他测试错误地使用另一个配置(Tear Down)。

http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx


Vla*_*lad 4

在我看来,您不需要在每个类中都考虑到 DI。我会使用以下策略:

  1. 确定模块边界。
  2. 在同一模块中,尽可能使用具体类。
  3. 对于模块间通信,尽可能使用 DI。

模块应该是相对细粒度的。

有一些常见的地方需要使用 DI,通常是可替换的数据源和(不常见的)算法。使用常识来检查某些东西是否需要更换。如果您发现某些东西需要 DI 或遭受 DI 困扰,请毫不犹豫地进行早期重构。