我正在开发一个使用Doctrine 2 ORM的Symfony 2.3项目.正如预期的那样,功能被拆分并分组为大多数独立的捆绑包,以允许在其他项目中重用代码.
我有一个UserBundle和一个ContactInfoBundle.联系信息被拆分,因为其他实体可能具有关联的联系信息,但是在用户不需要所述联系信息的情况下构建系统并不是不可能的.因此,我非常希望这两个不共享任何硬链接.
但是,创建从User实体到ContactInfo实体的关联映射会在BundIn被禁用时立即创建对ContactInfoBundle的硬依赖关系Doctrine会抛出ContactInfo不在其任何已注册的命名空间内的错误.
我的调查发现了一些应该对付它的策略,但它们似乎都没有完全发挥作用:
Doctrine 2的ResolveTargetEntityListener
只要接口在运行时实际被替换,这就可以工作.因为bundle依赖应该是可选的,所以很可能没有具体的实现可用(即没有加载contactInfoBundle)
如果没有目标实体,整个配置会崩溃到自身,因为占位符对象不是实体(并且不在/ Entity命名空间内),理论上可以将它们链接到实际上没有做任何事情的Mock实体.但是这个实体然后得到它自己的表(并且它被查询),开辟了一整套新的蠕虫.
反转关系
对于ContactInfo,它最有意义的是User成为拥有者,使ContactInfo成为拥有者成功避开依赖的可选部分,只要涉及两个bundle.但是,只要第三个(也是可选的)bundle希望与ContactInfo建立(可选)链接,使ContactInfo成为拥有者,就会在第三个bundle上创建一个来自ContactInfo的硬依赖.
使用户拥有的逻辑是一个特定的情况.然而,问题是通用的,其中实体A包含B,而C包含B.
使用单表继承
只要可选捆绑包是唯一与新添加的关联进行交互的捆绑包,就为每个捆绑包提供自己的用户实体,扩展UserBundle\Entities\User可以正常工作.但是,拥有多个扩展单个实体的捆绑包会导致这种情况变得有点混乱.你永远无法完全确定哪些功能在哪里可用,并且控制器以某种方式响应打开和/或关闭的捆绑(由Symfony 2的DependencyInjection机制支持)变得非常不可能.
欢迎任何有关如何规避此问题的想法或见解.经过几天跑进砖墙后,我的想法很新鲜.人们会期望Symfony有一些方法可以做到这一点,但文档只提供了ResovleTargetEntityListener,这是次优的.