php - 数据映射器模式中 Symfony 依赖注入(inject)组件的循环依赖

标签 php symfony dependency-injection datamapper circular-dependency

想象 2 个实体 - 用户和组。用户总是在一个组中,并且一个组总是有一个 super 用户。这些实体类只保存数据(没有逻辑)。

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

  • UserMapper 在查询 User 时需要 GroupMapper 来检索 User 的 $group
  • GroupMapper 在查询 Group 时需要 UserMapper 来检索 Group 的 $superuser

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

以下是该方案的说明:

Problem illustration

最佳答案

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

  • Mapper 是一个接口(interface)
  • GroupMapper实现Mapper,通过注入(inject)接收SL
  • UserMapper实现Mapper,通过注入(inject)接收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 是获得 DIC 的 UserMapper 实例,它需要使用组映射器服务: $um->sl->get('user') 返回组映射器。

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

另一种可能性是让您的服务 ContainerAware 并在相同的环境中使用它,但恕我直言,这更糟糕,尽管有点短,因为您基本上允许使用 DIC 中的任何内容而无需任何控制。我建议的模式最大限度地减少了“接触面”。

关于php - 数据映射器模式中 Symfony 依赖注入(inject)组件的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21368882/

相关文章:

reactjs - 无法使用React将nginx代理设置为Docker容器

php - 覆盖翻译器 Symfony2

c# - 以编程方式检查统一容器类型注册

php - 把自己设定为初学者练习PHP有什么好的项目?

php - 将 CodeIgniter 网站移动到新域但同一主机

php - Yii2 注销特定用户

PHP正则表达式的单词短语语法?

php - Symfony - DateTime 类的对象无法转换为字符串

java - 如何将应用程序上下文注入(inject)到 AspectJ 切面中?

javascript - AngularJS:从第三方库访问工厂或服务