DI容器对工厂有什么好处?

时间:2012-03-08 21:54:03

标签: dependency-injection ioc-container

这里有很多关于此的讨论,但似乎没有人真正回答这个问题。

我目前正在考虑使用Symfony 2 service container。我看的越多,看起来我就可以用服务工厂做同样的事了。请考虑以下示例:

services.yml

services:
    my_mailer:
        class:        Acme\Mailer
        arguments:    [sendmail]
    newsletter_manager:
        class:     Acme\Newsletter\NewsletterManager
        arguments: [@my_mailer]

现在要获得一名时事通讯经理,我会这样做:

// this has been configured with the above yml file
$serviceContainer = new ServiceContainer();
$newsletterManager = $serviceContainer->get("newsletter_manager");

但是,请考虑以下工厂样式代码:

class ServiceContainer
{
    public function getMyMailer()
    {
        return new Acme\Mailer("sendmail");
    }

    public function getNewsletterManager()
    {
        return new Acme\Newsletter\NewsletterManager($this->getMyMailer());
    }
}

然后使用它:

$serviceContainer = new ServiceContainer();
$newsletterManager = $serviceContainer->getNewsletterManager();

这里有什么我想念的吗?因为如果工厂可以为我做所有这些,我真的没有看到使用DI容器的优势。

我听说使用工厂导致你的代码“依赖于工厂”。我要么不明白这个论点,要么反对工厂的人是混淆的。只有顶级类(组合根)才能引用工厂,就像它是唯一一个引用DI容器一样。

1 个答案:

答案 0 :(得分:2)

  

我有什么东西在这里失踪吗?因为我没有真正看到   使用DI容器的优势,如果工厂可以完成所有这些   我

是的 - 您正在使用Service Locator (anti-)pattern使用您的DI容器,而不是将您的依赖项注入您的类。你的班级根本不应该参考你的DI容器。

相反,应该只有一个聚合根,您可以在其中创建容器并解析所有依赖关系。一旦解决了顶级类实例,然后使用Hollywood Principle使用IoC容器解析所有依赖项(以及依赖项的依赖项等) - 当创建类实例时,将传递其所有依赖项在,实例从不要求依赖本身。