在数据映射器模式中与Symfony的依赖注入组件的循环依赖关系

时间:2014-01-26 20:38:43

标签: php symfony dependency-injection datamapper circular-dependency

想象一下2个实体 - 用户和组。用户始终在一个组中,一个组始终有一个超级用户。这些实体类只保存数据(没有逻辑)。

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

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

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

以下是该计划的说明:

Problem illustration

1 个答案:

答案 0 :(得分:0)

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

  • Mapper是一个界面
  • GroupMapper实现Mapper,通过注入接收SL
  • UserMapper实现Mapper,通过注入接收SL
  • SL有方法:
    • 功能寄存器($ name,Mapper m)
    • function get($ name):Mapper
  • GroupMapper :: __ construct(SL $ sl,...)包括:
    • $ this-> sl = $ sl;
    • $ this-> sl->注册(' group',$ this);
  • UserMapper :: __ construct(SL $ sl,...)包括以下内容:
    • $ this-> sl = $ sl;
    • $ this-> sl->注册('用户',$ this)

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

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

另一种可能性是让你的服务ContainerAware并在同一个地方使用它,但恕我直言这更糟糕,虽然有点短,因为你基本上允许使用任何来自DIC而没有任何控制。我建议的模式最小化了接触面"。