依赖注入容器与注册表模式

时间:2013-06-17 07:46:40

标签: php oop design-patterns dependency-injection

据我所知,依赖注入原则就是解耦代码。而不是在类中创建实例,而是注入它们,而不是它们 松耦合。

现在如果我必须传递一组将在我的应用程序中通过几个类使用的对象,我可以创建一个容器(通常称为依赖注入容器)。

这正是我正在做的事情,因为我必须传递一个配置对象,一个记录器对象,一个翻译器对象等,它将通过我的应用程序的几个类实例使用。我将整个容器传递给几个类,即使并非所有类都需要访问容器中的所有对象。这引出了以下问题:如果我创建一个全局注册表并将对象放在那里,然后检索它们就像Registry :: getInstance() - > get('logger'); ?我使用全局注册表或依赖容器,类isntances可以访问容器或注册表中的所有对象,即使他们不需要查看/访问所有对象。

结论:如果我在我的类或全局注册表中传递依赖注入容器有什么区别?

3 个答案:

答案 0 :(得分:6)

  

注意:有时人们会使用不同名称的注册表。我所看到的常见问题:定位器,上下文和系统。

使用全局注册表会导致您的代码与所述注册表的类名绑定。这意味着您无法独立测试代码。而且,注册表的设置方式就在于你:你永远不知道需要哪个实例。

  

人们常常将DI容器与注册管理机构混淆。

DI容器不是你注入课堂的东西。相反,它是对工厂的增强:它确定类Foo需要在构造函数中注入Bar的实例。然后,根据设置,它要么获取Bar的新实例,要么使用现有实例来提供所述依赖关系。

  • 在一个简单的工厂中,您通常必须硬编码将被注入的依赖项。在这种情况下,工厂可以建造什么,受到足迹的限制"班级建设者。

  • 当工厂用作DI容器时,它可以生成具有各种依赖关系的实例。在此设置中,您的工厂专注于构建与某些特定名称空间(或其他高级)逻辑类组相关联的实例。

答案 1 :(得分:5)

我认为这里缺少的是CompositionRoot。根据DI原则,一旦在Composition Root中定义了绑定,就可以在整个应用程序中使用该引用。这就是DI Container带来的价值。

根据定义“组合根是应用程序中一个(最好)唯一的位置,模块一起组成。”

我将添加一个组合根也是一个独特的位置,其中所有关于应用程序行为的重要决策都会发生。这就是在什么情况下使用的对象。这是OO系统的核心,其中对象之间的交互提供了系统的行为。

答案 2 :(得分:0)

我同意teresko所说的大部分内容,我想补充一些观点:

  • 如果您认为您的服务是在许多不同的实例之间共享的,那么您可以将它们注册为带有容器的Singeltons,但如果这是您的问题,则必须考虑多线程。
  • 每当您在依赖注入方案中感觉到背部靠墙时,请记住工厂(Abstract Factory Pattern)几乎总是解决方案。
  • 您提到的服务似乎是一个跨领域的问题,因此我会使用AOP技术来避免使用这些问题使我的代码库膨胀,这将使代码更加清晰。