【问题标题】:Doctrine resolve_target_entities in custom bundle configuration自定义捆绑配置中的学说 resolve_target_entities
【发布时间】:2017-06-26 01:05:54
【问题描述】:

我制作了一个 Symfony 3 捆绑包,其中包含抽象模型以进一步扩展。类似于 FOS\UserBundle 中的 User 模型。但是,与 FOS 的 Bundle 不同,我还需要在这些模型\实体之间建立关系。我已经通过接口和 Doctrine 一点点(呵呵,几乎是字节)的配置来做到这一点。所以,现在,我必须做两件事来配置 - 比如说 - My\CustomBundle。

在 app/config/config.yml 我必须添加:

[...]
doctrine:
    orm:
[...]
        resolve_target_entities:
            My\CustomBundle\Model\Entity1Interface: AppBundle\Entity\Entity1
            My\CustomBundle\Model\Entity2Interface: AppBundle\Entity\Entity2
[...]

还有 My\CustomBundle 配置:

my_custom:
    doctrine:
        entity_1_class: AppBundle\Entity\Entity1
        entity_2_class: AppBundle\Entity\Entity2

正如您所看到的,配置有点混乱和重复,因为教义.orm 部分。我希望我可以通过在 My\CustomBundle 中自动执行它来避免它。有没有可能这样做?

【问题讨论】:

    标签: php symfony doctrine-orm doctrine


    【解决方案1】:

    您可以在编译器通行证的帮助下完成。根据 my_custom 捆绑配置添加编译器通道,将更改 resolve_target_entities。

    CompilerPass:

    namespace My\CustomBundle\DependencyInjection\Compiler;
    
    use Doctrine\ORM\Version;
    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    class DoctrineResolveTargetEntityPass implements CompilerPassInterface
    {
        /**
         * {@inheritdoc}
         */
        public function process(ContainerBuilder $container)
        {
            // resolve_target_entities
            $definition = $container->findDefinition('doctrine.orm.listeners.resolve_target_entity');
    
            $definition->addMethodCall('addResolveTargetEntity', array(
                $container->getParameter('my_custom.doctrine.entity_1.resolve_from'), // My\CustomBundle\Model\Entity1Interface
                $container->getParameter('my_custom.doctrine.entity_1.resolve_to'), // AppBundle\Entity\Entity1
                array(),
            ));
    
            if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) {
                $definition->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata'));
            } else {
                $definition->addTag('doctrine.event_subscriber', array('connection' => 'default'));
            }
        }
    }
    

    并在你的包中注册这个编译器传递

    namespace My\CustomBundle;
    
    use Symfony\Component\HttpKernel\Bundle\Bundle;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\DependencyInjection\Compiler\PassConfig;
    use My\CustomBundle\DependencyInjection\Compiler\DoctrineResolveTargetEntityPass;
    
    class MyCustomBundle extends Bundle
    {
        public function build(ContainerBuilder $container)
        {
            parent::build($container);
            $container->addCompilerPass(new DoctrineResolveTargetEntityPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1000);
        }
    }
    

    【讨论】:

    • 像魅力一样工作。有没有可能用教义.dbal.types 做到这一点?我还在我的包中使用了两种自定义枚举类型,我还希望它们在启用我的包后自动注入到应用程序中。
    • 你知道我怎样才能用教义.dbal.types 实现这个技巧吗?我在 Doctrine 中看不到任何准确的事件监听器
    • 我不能说,我在 bundles 中没有自定义类型。
    猜你喜欢
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多