Symfony 3.4 - не может переписать службу расширения веток - PullRequest
0 голосов
/ 11 декабря 2019

Удаленный пакет имеет класс расширения LogEntryExtension Twig, который я хочу перезаписать (Remote\Framework\DoctrineBundle\Twig\LogEntryExtension).

Пакет зарегистрирован вместе с outhers в файле bundles.php ...

// bundles.php
return [
    ...
    'Remote\Framework\DoctrineBundle\RemoteFrameworkDoctrineBundle' => ['all' => true],
];

... и загружается в пользовательский класс AppKernel с использованием MicroKernelTrait. Сервисы также загружаются внутри класса:

class AppKernel extends Kernel
{
    use MicroKernelTrait;

    ...

    public function registerBundles(): iterable
    {
        $contents = require dirname(__DIR__).'/config/bundles.php';
        foreach ($contents as $class => $envs) {
            if (isset($envs['all']) || isset($envs[$this->environment])) {
                yield new $class();
            }
        }
    }    

    protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
    {
        ...
        $confDir = dirname(__DIR__).'/config';
        ...

        $loader->load($confDir.'/services.yml', 'glob');
    }
}

Общая конфигурация работает, поэтому она не свежая, другие сервисы также работают без проблем. Вот конфигурация службы внутри services.yml, включая перезапись удаленного LogEntryExtensions нашим собственным:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: public

    App\:
        resource: '../src/*'
        exclude: '../src/{Annotation,DataFixtures,Entity,EntityTrait,Event,Exception,Form,DoctrineMigrations,Hideable,Integrator,Model,Repository,Statistic,Tag,Util}'

    App\Form\:
        resource: '../src/Form/{EventSubscriber,Type}'

    ...

    # This is not necessary since autowiring is true, but i added it for completeness:
    App\Twig\LogEntryExtension:
        arguments: ['@doctrine.orm.entity_manager', '@translator']


    # Here we overwrite the remote service:
    remote_framework_doctrine.twig.logentry_extension:
        public: false
        autoconfigure: false
        class: App\Twig\LogEntryExtension
        arguments: ['@doctrine.orm.entity_manager', '@translator'] # Also normally unnecessary!
        tags:
            - { name: twig.extension }    

Наш класс LogEntry имеет следующие параметры конструктора:

namespace App\Twig;

use Twig\Extension\AbstractExtension;

class LogEntryExtension extends AbstractExtension
{
    // private members

    // Just that you know they aren't wrong!
    public function __construct(EntityManagerInterface $em, TranslatorInterface $translator)
    {
        // Initializers
    }

    ...
}

Теперь становится интересно, что сама удаленная служба LogEntryExtension имеет необязательный параметр конструктора ...

use Remote\Framework\DoctrineBundle\Entity\LogEntry;

class LogEntryExtension extends \Twig_Extension
{
    // members

    public function __construct(ObjectManager $manager, $logEntryClass = LogEntry::class)
    {
        $this->manager = $manager;
        $this->logRepo = $manager->getRepository($logEntryClass);
    }

    ...

}

... но в определении службы указывается только диспетчер сущностей:

remote_framework_doctrine.twig.logentry_extension:
    public:    false,
    class:     Remote\Framework\DoctrineBundle\Twig\LogEntryExtension
    arguments: [ '@doctrine.orm.entity_manager' ]
    tags:
        - { name: twig.extension }

Для меня все выглядит хорошо. Symfony должен инициализировать мое определение logentry_extension вместо удаленного, но теперь я получаю очень странную ошибку ...

Сообщение: «Аргумент 2 передан в App \ Twig \ LogEntryExtension ::__construct () должен реализовывать интерфейс Symfony \ Component \ Translation \ TranslatorInterface, заданная строка, вызывается в C: \ Users \ Rene \ Documents \ Repos \ susi1 \ var \ cache \ dev \ Container4wi0fox \ appDevDebugProjectContainer.php в строке 4061 "

При взгляде внутрь контейнера проекта обнаруживается странный вызов:

/**
 * Gets the public 'remote_framework_doctrine.twig.logentry_extension' shared autowired service.
 *
 * @return \App\Twig\LogEntryExtension
 */
protected function getRemoteFrameworkDoctrine_Twig_LogentryExtensionService()
{
    return $this->services['remote_framework_doctrine.twig.logentry_extension'] = 
    new \App\Twig\LogEntryExtension(
        ${($_ = isset($this->services['doctrine.orm.default_entity_manager']) ? 
        $this->services['doctrine.orm.default_entity_manager'] : 
        $this->getDoctrine_Orm_DefaultEntityManagerService()) && false ?: '_'}, 

        'Remote\\Framework\\DoctrineBundle\\Entity\\LogEntry'
    );
}

Для инициализации службы Symfony правильно использует наш класс App\Twig\LogEntryExtension, но инициализирует его с помощью параметра конструктора по умолчанию оригиналаremote LogEntryExtension ...

Я также попробовал некоторые варианты приведенного выше определения службы, всегда с одинаковыми результатами.

Так почему Symfony не перезаписывает службу App\Twig\LogEntryExtension правильно иинициализирует его с определенным параметром translator?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...