php - Symfony - Get a container inside an Interface

one text

Solution:

As mentioned in my comment, you should utilize dependency injection to add only the services you need instead of the entire container.

Be sure to clear and warmup your Symfony cache after making the changes below.

autowire services

In Symfony 3.4+ you can utilize autowire, which will automatically inject known FQCN services into the __construct for example using the logger service.

vendor/symfony/monolog-bundle/Resources/config/monolog.xml

<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="monolog.logger" parent="monolog.logger_prototype" public="false">
            <argument index="0">app</argument>
            <call method="useMicrosecondTimestamps">
                <argument>%monolog.use_microseconds%</argument>
            </call>
        </service>
        <service id="logger" alias="monolog.logger" />

        <service id="Psr\Log\LoggerInterface" alias="logger" public="false" />

        <!-- ... -->

        </service>
    </services>
</container>

config/services.xml

<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <!-- attempts to inject and tag services automatically -->
        <defaults autowire="true" autoconfigure="true" public="false"/>

        <service id="RegistrationExtension\Storefront\Controller\RegistrationExtensionController" public="true"> </service>
        <service id="RegistrationExtension\Subscriber\RegisterExtensionSubscriber">
            <tag name="kernel.event_subscriber"/>
        </service>
    </services>
</container>

src/RegistrationExtension/Subscriber/RegisterExtensionSubscriber.php

use Psr\Log\LoggerInterface;

class RegisterExtensionSubscriber implements EventSubscriberInterface 
{
    private $logger;

    public function __construct(LoggerInterface $logger) 
    {
         $this->logger = $logger;
    }
}

Dependency Injection

If the service can not use autowire to be injected because it uses a string service name instead of FQCN you can manually declare the service in your config.

config/services.xml

<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>

        <service id="RegistrationExtension\Storefront\Controller\RegistrationExtensionController" public="true"> </service>
        <service id="RegistrationExtension\Subscriber\RegisterExtensionSubscriber">
            <argument type="service" id="mail_template_type.repository" />
            <argument type="service" id="mail_template.repository" />
            <tag name="kernel.event_subscriber"/>
        </service>
    </services>
</container>

src/RegistrationExtension/Subscriber/RegisterExtensionSubscriber.php


use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
//...

class RegisterExtensionSubscriber implements EventSubscriberInterface 
{

    /**
     * @var EntityRepositoryInterface
     */
    private $mailTypeRepository;

    /**
     * @var EntityRepositoryInterface
     */
    private $mailRepository;

    public function __construct(
        EntityRepositoryInterface $mailTypeRepository,
        EntityRepositoryInterface $mailRepository
    ) {
         $this->mailTypeRepository = $mailTypeRepository;
         $this->mailRepository = $mailRepository;
    }

    public function onCustomRegister(AccountLoginPageLoadedEvent $event)
    {        
        $mailEntity = $this->mailTypeRepository->search(
            (new Criteria())->addFilter(new EqualsFilter('mail_template_type.technicalName', "customer_register")),
            $event->getContext()
        );

        if ($mailType = $mailEntity->getEntities()->first()) {
            $mailEntity = $this->mailRepository->search(
                (new Criteria())->addFilter(new EqualsFilter('mail_template.mailTemplateTypeId', $mailType->getId())),
                $event->getContext()
            );
        
            $mail = $mailEntity->getEntities();
            //...
        }
    }
}

Source