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

Mat*_*hew 8 php oop design-patterns dependency-injection

我知道依赖注入原则就是解耦代码.而不是在类中创建实例,而是注入它们,这使它们松散耦合.

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

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

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

ter*_*ško 6

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

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

人们常常将DI容器与注册表混淆.

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

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

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


Seb*_*rge 5

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

根据定义"组合根是应用程序中的一个(最好)唯一的位置,其中模块组合在一起."

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

  • 这篇文章回答了我的上一篇评论:http://richardmiller.co.uk/2011/07/07/dependency-injection-moving-from-basics-to-container/ (2认同)