繁体   English   中英

数据映射器模式中具有Symfony依赖注入组件的循环依赖

[英]Circular dependency with Symfony's dependency injection component in a data mapper pattern

想象2个实体-用户和组。 用户总是在一个组中,而一个组中总是有一个超级用户。 这些实体类仅保存数据(那里没有逻辑)。

这两个实体都有Mapper类(处理SQL查询):UserMapper和GroupMapper。 两者在查询实体时都相互依赖:

  • 查询用户以检索用户的$ group时,UserMapper需要GroupMapper
  • 查询组以检索组的$ superuser时,GroupMapper需要UserMapper

我一直在使用Symfony的依赖项注入组件将依赖项注入到构造函数中。 但是在这种情况下,我遇到了这种方法的麻烦。 我知道我可以使用像Doctrine这样的ORM来为我处理这个问题,但是目前这不是一个选择。 什么是最干净/最好的解决方案?

这是该方案的说明:

问题图

一种可能的方法是引入第三个服务SL并注入它,如下所示:

  • 映射器是一个接口
  • GroupMapper实现Mapper,通过注入接收SL
  • UserMapper实现Mapper,通过注入接收SL
  • SL具有以下方法:
    • 功能寄存器($ name,Mapper m)
    • 函数get($ name):映射器
  • GroupMapper :: __ construct(SL $ sl,...)包括以下内容:
    • $ this-> sl = $ sl;
    • $ this-> sl-> register('group',$ this);
  • UserMapper :: __ construct(SL $ sl,...)包括以下内容:
    • $ this-> sl = $ sl;
    • $ this-> sl-> register('user',$ this)

然后,假设$ um是UserMapper的实例,则获得了DIC,并且它需要使用组映射器服务:$ um-> sl-> get('user')返回组映射器。

从本质上讲,这归结为实现服务定位器,这虽然不是很好,但是却具有很小的优势,本质上是完整DIC的过滤子集。 只要您在初始化所有相互依赖的服务之前没有开始使用这两种服务,这将起作用,这在某些情况下可能不太适合。

另一种可能性是使服务ContainerAware并以相同的方式使用它,但是恕我直言,这虽然更短了点,但更糟,因为您实际上允许在没有任何控制的情况下使用DIC中的任何内容。 我建议的图案可以最大程度地减少“接触表面”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM