【问题标题】:What parts of a PHP website are handled by a Dependency Injection Container?PHP 网站的哪些部分由依赖注入容器处理?
【发布时间】:2012-02-02 20:09:41
【问题描述】:

在阅读了关于 Dependency Injection Containers 的一万亿篇含糊不清的教程后,我觉得我仍然没有完全理解这一点。

当涉及到特定于应用程序的事物(如模型、控制器等)时,我应该如何管理依赖项的自动注入?

我碰巧有一个大型网站,可能有 30-40 种不同类型的模型...我真的要创建一个应用程序依赖管理器来处理这些不同类型中的每一种吗?

有人告诉我,DIC 不是针对领域的东西,而是更多地针对框架的东西,我也听说过相反的情况。

哪个是“对的”?

额外问题:

如果 DIC 不适用于域层对象(如模型),您如何将依赖关系传递给域层对象?

【问题讨论】:

  • 顺便说一句,我意识到技术上没有一个“正确”的答案......但在哲学之间的一些解释将不胜感激。
  • 另外,我似乎看到的大多数教程示例实际上都是针对商业模式的......比如“ShippingService”等......混淆在......

标签: php design-patterns dependency-injection


【解决方案1】:

也许不完全是您正在寻找的,但这里是依赖注入容器 (DIC) 的示例用法

假设我有一个Database class 和一个Cache class。我需要能够在我的其他类(模型、控制器等)中访问我的数据库和我的缓存类。

这是一个 DIC 会派上用场的情况,我可以简单地将我的数据库和缓存类存储在 DIC 类中,并将该 DIC 类传递给需要访问它所拥有的对象的任何其他类

【讨论】:

  • 好吧,我已经开始看得更清楚了。但是,通过这种方式,您将 DIC 类半描述为(不要杀死我)服务定位器,用于注入到域层对象中的框架级服务(而不是一些单例或全局变量)。对吗?
  • 顺便说一句,如果是这样,那我完全明白了。哈哈,我不是这个意思作为答案的刺。
  • 对我来说,DIC 基本上只是一个容器,它包含我需要传递和经常访问的任何对象,而不是传递/注入多个对象,我能够简单地传递/注入 DIC 对象并且该对象可以包含需要在整个应用程序中使用的多个其他对象
  • 有趣。我还读到将 DIC 传递给其他对象有点违背了目的,因为它创建了一个选项来“拉”你的依赖项,因此不再注入它们。在那种情况下,我们似乎失去了对对象的控制?
  • 恐怕我没有真正遵循,DIC只是一个容器,你将它传递到需要它的地方,如果我有10个我需要在多个其他对象中访问的对象,而不是手动将所有 10 个对象注入 X 数量的其他对象,我可以简单地将它们注入我的容器,然后将容器注入这 10 个对象。听起来您可能将 DIC 与 inversion of control en.wikipedia.org/wiki/Inversion_of_control 混淆了
【解决方案2】:

这个问题不是很清楚,但我会尝试。

当涉及到特定于应用程序的事物(例如模型、 控制器等),我应该如何管理自动注入 依赖?

您使用 DIC 吗?你写了一个,还是使用了一个库?

也许一个库会有所帮助,我是 PHP-DI 的作者,所以我有偏见,但该库帮助我自动注入依赖项。

例如我可以写:

class UserController
{
    private $formFactory;

    public function __construct(FormFactory $formFactory) {
        $this->formFactory = $formFactory;
    }

    public function createForm($type, $data, $options) {
        // $this->formFactory->...
    }
}

在这种情况下,DIC 可以检测您的控制器想要的依赖项,并自动注入它们。这让生活更轻松。

我碰巧有一个大型网站,大概有 30-40 种不同类型的 模型...我真的要创建一个单一的应用程序依赖管理器吗? 处理这些不同的类型?

你为什么需要那个?我不明白需要,也许你需要多解释一下问题是什么。

有人告诉我,DIC 不适用于域内容, 但更多是关于框架的东西,我也听说过相反的情况。

哪个是“对的”?

IMO “域内容”和“框架内容”之间没有区别。唯一困难的是,有一个 DIC 在实体中注入东西,因为这不是“单例”(不是单例模式的方式):这些对象不是由 DIC“管理”的,您可以手动创建实例在您的代码中无处不在。示例:

$user = new User();

如果 User 类需要服务,那么您必须在代码中的任何地方做:

$user = new User($service);

相反,您永远不需要手动创建服务(您永远不需要调用“new”),因此您可以让容器创建实例并注入所有内容。


我对我的回答不太满意,因为它有点含糊,但我很难确定你的问题到底是什么。也许你应该给出代码示例,或者至少解释一下。

PS:我一直在努力理解 DI 以及什么是 DIC,不要满足于“我想我现在明白了一点,虽然不是完全明白”,我也是这样做的,我花了几个月的时间才明白终于明白了。

如果有帮助,请阅读http://mnapoli.github.io/PHP-DI/ 的介绍文本,也可以阅读:http://mnapoli.fr/controllers-as-services/(不直接相关,但可以提供帮助)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-15
    • 2022-10-22
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    相关资源
    最近更新 更多