Symfony 3.4-无法覆盖树枝扩展服务

时间:2019-12-11 18:02:11

标签: php symfony service doctrine autowired

远程捆绑软件有一个LogEntryExtension Twig扩展类,我想覆盖它(Remote\Framework\DoctrineBundle\Twig\LogEntryExtension)。

该捆绑包与外围产品一起注册在bundles.php文件中...

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

...并使用MicroKernelTrait加载到自定义AppKernel类中。服务也加载到该类中:

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的定义,而不是远程的定义,但是现在我得到一个非常奇怪的错误...

  

消息:“传递给App \ Twig \ LogEntryExtension :: __ construct()的参数2必须实现接口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类,但使用原始远程LogEntryExtension的默认构造函数参数对其进行初始化...

我还尝试了上述服务定义的一些变体,总是得到相同的结果。

Symfony为什么不正确覆盖App\Twig\LogEntryExtension服务,并使用定义的translator参数对其进行初始化?

0 个答案:

没有答案