user4898812
user4898812

Reputation:

Symfony2 Dependency Injection the "Right Way"

This is a fairly open question, i'm looking for opinion more than anything...

Coming from Laravel, Dependency Injection (DI) was blissful, if you wanted to access a method from a class, you could either inject it by type hinting in the method or constructor and you'll have instant access to it; symfony2 doesn't seem this simple from the face of it.

We've got service containers, setter injection, constructor injection by setting up a service yml where you pre-define your arguments, but this just seems dirty.

So the "Laravel Way" of dependency injection is done like this

class Listener
{
    protected $mailer;

    public function __construct(Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    public function userWasAdded(User $user)
    {
        // Do some stuff...

        $this->mailer->send('emails.welcome', ['user' => $user], function($message)
        {
            $message->to($user->email, $user->name)->subject('Welcome!');
        });
    }
}

How could I, in Symfony2, replicate Laravel's form of dependency injection, this seems like a whole cleaner way of doing things, or perhaps there is a Symfony2 way of doing things I haven't yet discovered. Any help is appreciated.

Upvotes: 0

Views: 293

Answers (1)

Tomasz Madeyski
Tomasz Madeyski

Reputation: 10890

I'm not familiar with Laravel but after reading doc I believe that DI in Laravel and Symfony are quite similar after all.

From the doc:

There is no need to bind classes into the container if they do not depend on any interfaces. The container does not need to be instructed on how to build these objects, since it can automatically resolve these objects using reflection.

In this case, Symfony has similar feature starting from 2.8 version which is auto wiring

In other case (meaning that class has constructor dependencies) you need to instruct your framework how to resolve these dependencies. Only difference here is that you have to do it in different ways.

In Symfony most common way is just to use yml file:

services:
    mailer:
        class:     Mailer
        arguments: ['%mailer.transport%']

But you can do it in xml or php as well (check the doc)

$container->setParameter('mailer.transport', 'sendmail');
$container
    ->register('mailer', 'Mailer')
    ->addArgument('%mailer.transport%');

But in Laravel it is the same: you need to instruct framework how to instantiate objects

$this->app->bind('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app->make('HttpClient'));
});

Which option to choose to setup container (yml, xml, php) is just a matter of taste.

Upvotes: 1

Related Questions