Удаленный пакет имеет класс расширения 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
?