0

I try to inject the symfony service container into a dcotrine dynamic connection wrapper_class

use Doctrine\DBAL\Connection;    
class DynamicConnection extends Connection
{
    public $container;

    /**
     * @required
     * @param $container
     */
    public function setContainer(ContainerInterface $container)
    {
        $this->container = $container;
    }
}

I also tried to inject it with the service.yaml

    App\Service\Database\DynamicConnection:
    calls:
        - [setContainer, ['@service_container']]

But this is also not working. How can i inject the service container here? My goal here is to get a variable of the service container:

$this->container->get('my.string.variable')
Seanny123
  • 8,776
  • 13
  • 68
  • 124
dom
  • 1
  • 1
  • Doctrine itself knows nothing about the container. Doctrine creates the connections using the new operator. There is simply no place to hook in a container that I know of. You could access the container globally ($kernel->getContainer()) though that tends to be frowned upon. Maybe a [kernel request listener](https://symfony.com/doc/current/components/http_kernel.html#the-kernel-request-event) that modifies the connection early in the request processing cycle. But don't inject the whole container if all you need is a parameter. – Cerad Dec 10 '18 at 14:20
  • And if you are not using the entity manager at all then it is easy enough to [define your own doctrine connection factory](https://stackoverflow.com/questions/47620275/how-to-register-the-dbal-doctrine-connection-as-a-service-without-the-doctrinebu/47635677#47635677) completely independent of the doctrine bundle. – Cerad Dec 10 '18 at 14:28
  • Ok, global $kernel; $kernel->getContainer(); worked for me. Thanks for the hint. – dom Dec 10 '18 at 21:43
  • Glad you got it working. Just be aware that using globals in Symfony is considered to be a very very bad thing indeed. Ultimately it would be better to learn how to do things the "right" way. – Cerad Dec 10 '18 at 21:49
  • I found that this [answer](https://stackoverflow.com/a/53301465/4640060) very useful in your case – isom Sep 23 '19 at 15:11
  • If all you want is a parameter, why not put it as a env variable and use getenv() instead ? – Mouke Jun 30 '20 at 13:53

1 Answers1

3

You can do this by adding a CompilerPass. For simple CompilerPass, you can add it directly in your application Kernel class by implementing CompilerPassInterface:

class Kernel extends BaseKernel implements CompilerPassInterface
{
    use MicroKernelTrait;

    ...


    public function process(ContainerBuilder $container)
    {

       $container
          ->getDefinition('doctrine.dbal.default_connection')
          ->addMethodCall('setContainer', [
             new Reference('service_container')
           ]);
    }

}

Note however that as mentioned by other users, this is not a very good practice. You should inject what you need precisely instead of Container service.

sunix
  • 146
  • 1
  • 8