What are the benefits of making a DI container more than a factory?

There is a lot of discussion about this, but nobody seems to really answer the question.

I am currently considering using a Symfony 2 service container . The more I look at it, the more it looks like I could do the same with a factory service. Consider the following example:

services.yml

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

      

Now, to get the news manager, I do something like:

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

      

However, consider the following factory style code:

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

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

      

And then using it:

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

      

Is there something I am missing here? Because I really don't see the benefit of using a DI container if a factory can do all of this for me.

I've heard that using factories makes your code "depend on a factory". I either don't understand this argument or the person arguing with factories is confused. Only the top level class (composition root) will have a reference to the factory, as it is, the only one to have a reference to the DI container.

+3


source to share


1 answer


Is there something I am missing here? Because I really don't see the benefit of using a DI container if a factory can do all of this for me.

Yes. You are using your DI container using Service Locator (anti-) instead of injecting your dependencies into your classes. Your class shouldn't reference your DI container at all.



Instead, there should only be one cumulative root where you create the container and resolve all dependencies. Once you have resolved an instance of a top-level class, all of its dependencies (and dependency dependencies, etc.) are then resolved using an IoC container using the Hollywood Principle - when instances of an instance are created, all of its dependencies are passed, the instance never requests itself dependence.

+2


source







All Articles