对使用IOC容器,服务定位器和工厂感到困惑 [英] Confused over using IOC container, service locator and factory

查看:111
本文介绍了对使用IOC容器,服务定位器和工厂感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个 BaseForm ,它取决于 ILogger IResourceManager 或类似的东西。当前,它使用服务定位器(我知道它是反模式)来解析所需服务的正确实现。

Suppose I have a BaseForm which depends on an ILogger or IResourceManager or something like that. Currently it resolves the correct implementation of the required service using the service locator which I know is an anti-pattern.


  • 正在使用构造函数注入解决这种依赖关系的正确方法?

  • 我是否必须在 BaseForm (及其派生类型)中注册我的 BaseForm (及其派生类型)?容器以创建具有已解决依赖关系的实例?这不是使所有事情复杂化吗?

  • 使用包裹在服务定位符周围的静态工厂是否很糟糕?

  • 除了单元测试之外,我还会吗?真的因为使用服务定位器反模式而受到惩罚?

  • Is using the constructor injection the right way to resolve this kind of dependency?
  • Do I have to register my BaseForm (and its' derived types) in the container in order to create instances of them with resolved dependencies? Doesn't that complicate everything?
  • Is it bad to use a static factory wrapped around a service locator?
  • Unit-testing aside, will I really be punished because of using service locator anti-pattern?

很抱歉一次问很多问题。我已经阅读了以下SO问题以及许多其他问题,但阅读它们只会使我感到困惑:

Sorry about asking many questions at once. I've read the following SO questions and many others but reading them only added to my confusion:

  • How to use Dependency Injection and not Service Locator
  • What's the difference between the Dependency Injection and Service Locator patterns?
  • How to avoid Service Locator Anti-Pattern?

推荐答案

应该始终使用依赖项注入,因为它具有一些明显的优势。但是,对于UI技术,并非总是可以使用依赖项注入,因为某些UI技术(例如,在.NET空间,Win Forms和Web Forms中)仅允许您的UI类(窗体,页面,控件等)具有默认构造函数。在这种情况下,您将不得不使用其他方法,即服务定位器。

If possible, you should always go with dependency injection, since it has a few clear strength. With UI technologies however, it is not always possible to use dependency injection, since some UI technologies (in .NET space, Win Forms and Web Forms, for instance) only allow your UI classes (forms, pages, controls, etc) to have a default constructor. In that case you will have to fall back to something else, which is service locator.

在这种情况下,我可以为您提供以下建议:

In that case I can give you the following advice:


  • 仅退回到Service Locator来处理不能由您的容器使用依赖项注入创建的UI类,以及对于您仍然无法进行单元测试的东西。

  • 尝试在这些UI类中实现尽可能少的逻辑(如不起眼的对象,仅包含与视图相关的内容。这样可以使您尽可能地进行单元测试。

  • 将容器包装在静态方法周围,以从应用程序的其余部分隐藏该容器。当无法解析依赖项时,请确保对该静态方法的调用失败。

  • 解析该类型的(默认)构造函数中的所有依赖项。这样,当创建该类型的应用程序之一无法解决依赖关系时(而不是稍后单击某些按钮时),应用程序就会快速失败。

  • 在应用启动过程中检查(或使用单元测试),是否可以创建所有这些UI类型。这使您不必遍历整个应用程序(通过打开所有表单)来查看DI配置中是否存在错误。

  • 当容器无法构建类型时,会出现没有理由在容器中注册它们。如果可以通过容器创建它们(例如使用ASP.NET MVC Controller类),则显式注册它们会很有用,因为某些容器允许您预先验证配置,这将检测到这些类型中的配置错误。

  • Only fall back to Service Locator for UI classes that can't be created by your container using dependency injection, and for stuff that you aren't unit testing anyway.
  • Try to implement as less logic as possible in those UI classes (as Humble objects with only view related stuff). This allows you to unit test as much as possible.
  • Wrap the container around a static method to hide the container from the rest of the application. Make sure that a call to this static method fails, when the dependency cannot be resolved.
  • Resolve all dependencies in the (default) constructor of that type. This allows the application to fail fast when one of its dependencies cannot be resolved when that type is created, instead of later on when some button is clicked.
  • Check during app start-up (or using a unit test), if all those UI types can be created. This saves you from having to go through the whole application (by opening all forms) to see if there is an error in the DI configuration.
  • When types cannot be built by the container, there is no reason to register them in the container. If they can be created by the container (such as with ASP.NET MVC Controller classes), it can be useful to register them explicitly, because some containers allow you to verify the configuration up front, which will detect configuration errors in those types right away.

除了单元测试外,还有其他两个反对使用Service Locator的重要论点,它们由Mark Seemann在他著名的博客文章服务定位器是反模式

Besides unit testing, there are two other important arguments against the use of the Service Locator, which are given by Mark Seemann in his famous blog post Service Locator is an Anti-Pattern:


  • 服务定位器隐藏类的依赖关系,导致运行时错误而不是编译时错误

  • 服务定位器正在使代码更难以维护

这篇关于对使用IOC容器,服务定位器和工厂感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆