Why do we use ContainerInterface when injecting @service_container as an argument?

2

In the file services.yml I have the following service configured:

services:
    api.response_factory:
        class: AppBundle\Api\ResponseFactory
        arguments: ['@service_container']

In class ResponseFactory I have the constructor method that gets the argument:

namespace AppBundle\Api;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;

public function __construct(Container $container)
{
    $this->container = $container;
}

Notice that the argument container is of type ContainerInterface .

If it's just an interface, how can the code below work?

$this->container->get('router')->generate('ROTA_A');
    
asked by anonymous 15.06.2016 / 12:12

1 answer

1

The method says that it accepts objects whose class implements the ContainerInterface interface. It does not mean that you are getting an instance of an interface - that would be impossible.

In the case of the above code, you are getting an instance of the Container class (which, in turn, implements the ContainerInterface interface). This is why, from the container, you can get the router service and thus generate the desired route.

Another thing: avoid injecting service containers into other services; prefer to inject individual services, so your code gets cleaner and more concise.

For example, if you want to inject only the router service (which is the same argument when you use the container get method), create your service definition as follows:

services:
    api.response_factory:
        class: AppBundle\Api\ResponseFactory
        arguments: ['@router']

And then change the constructor to receive an object that implements the class RouterInterface :

<?php

namespace AppBundle\Api;

use Symfony\Component\Routing\RouterInterface;

class ResponseFactory
{
    /** @var RouterInterface $router */
    protected $router;

    /**
     * @param RouterInterface $router
     */
    public function __construct(RouterInterface $router)
    {
        $this->router = $router;
    }
}

You can see all the services available in your application (including those you have created) by means of the command app/console container:debug (or bin/console debug:container in the case of Symfony 3 up).

    
15.06.2016 / 13:37