How NOT to pass The Symfony Dependency Injection Container as an argument

This is the (almost undocumented) best practice for using the dependency injection container in Symfony, so Sensiolabs Insights won’t return an error that states “The Symfony Dependency Injection Container should not be passed as an argument“.

Any class that needs to use the container service should implement the ContainerAwareInterface interface and in addition use the ContainerAwareTrait trait. Here’s an example with a Doctrine migration:

// app/DoctrineMigrations/Version20160809224144.php
namespace Application\Migrations;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;

class Version20160809224145 extends AbstractMigration 
    implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    public function up(Schema $schema)
    {
        // let's test it
        if ( $this->container instanceof ContainerInterface )
            dump( 'Darling, say hello to the container' );
    }

    public function down(Schema $schema)
    {
        // ...
    }
}

The above example assumes migrations are configured as the example from documentation in `config.yml`.

Another example

A a custom service that needs to be container aware – therefore this part needs two files modifications for configuration:

// src/AppBundle/Services/ExampleService.php
namespace AppBundle\Services;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;

class ExampleService implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    // ... stuff
}

# app/config/services.yml
services:
    app.example_service:
        class: AppBundle\Services\ExampleService
            calls:
                - [setContainer, [[email protected]_container']]

Note: it seems like PHPStorm prefers single quotes for passing the argument for method, so it won’t highlight it as an error.

Basically, anything that implements the ContainerAwareInterface gets the ContainerInterface injected via the setContainer method (from the trait), auto-magically-called. Well, except for services, because are constructed on demand, so they need the call in their definition as a result.

Leave a Reply

Your email address will not be published. Required fields are marked *