首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP如何防止pimple DIC在循环依赖上导致无限循环

PHP如何防止pimple DIC在循环依赖上导致无限循环
EN

Stack Overflow用户
提问于 2017-03-08 12:04:54
回答 3查看 493关注 0票数 2

在本例中,我将classAclassB与pimple容器一起使用。

它们都是相互依赖的。然而,当使用pimple DIC设置时,下面的代码会导致无限循环...

一定有办法在粉刺中做到这一点,但我在文档中看不到…有什么办法防止无限循环吗?

代码语言:javascript
复制
// PIMPLE CONTAINER
use Pimple\Container;
$container = new Container();

use Classes\ClassA;
$container['ClassA'] = function ($c) {
  return new ClassA($c['ClassB']);
};

use Classes\ClassB;
$container['ClassB'] = function ($c) {
  return new ClassB($c['ClassA']);
};
EN

回答 3

Stack Overflow用户

发布于 2017-03-08 15:11:11

严格地说,你的问题与粉刺无关。

你只有一个循环构造函数依赖,没有办法修复它们。A需要B需要A需要B。

问题是,通常情况下,两个相互依赖的类没有多大意义。但在极少数情况下,这两种方法中的一种应该是较轻的依赖项,即在实例化之后通过setter或类似的机制注入对象。

通过在ClassB中传递容器和实例化,您隐藏了依赖项,这超出了拥有依赖项注入容器的目的。现在ClassB依赖于Container,而不是您首先想要的ClassA

不要这样做,只需向ClassB添加一个方法setA(Class A $a)即可。

然后,在实际需要时通过调用$b->setA($container['ClassA']);来注入依赖项,而不是在DI容器上。作为Adam points out,您甚至可以通过扩展您的服务并在服务定义上使用setter来在容器中进行setter注入。

但是,再次重申,你的主要问题是有一个循环依赖。再想一想。这很可能是你的设计需要改进的一个标志。

票数 1
EN

Stack Overflow用户

发布于 2017-03-08 15:13:04

@yivi首先对循环引用的有效性进行了有效的观察in their answer。所以我真的认为你应该在这里评估你的设计。你可能是在治疗症状,而不是潜在的问题。我们不可能对此发表评论,尽管给出了您的通用示例代码(这是针对手头问题的好代码)。如果你认为你的设计是值得的,也许可以提出一个新的问题?要么在这里,要么在Code Review上?

如果您控制着ClassAClassB的设计,那么这种事情的规定方法就是使用setter注入,而不是构造函数注入。

这应该是可行的:

代码语言:javascript
复制
// PIMPLE CONTAINER
use Pimple\Container;
$container = new Container();

use Classes\ClassA;
$container['ClassA'] = function ($c) {
  return new ClassA();
};

use Classes\ClassB;
$container['ClassB'] = function ($c) {
  return new ClassB();
};


$container->extend('ClassA', function ($instanceOfA, $container) {
    $instanceOfA->setB($container['ClassB']);

    return $instanceOfA;
});

$container->extend('ClassB', function ($instanceOfB, $container) {
    $instanceOfB->setA($container['ClassA']);

    return $instanceOfB;
});

(未经测试,可能包含拼写错误,但这是一般要点)

请注意,原始构造函数不再接受依赖项,依赖项的插入将留给特定的setter。这允许您在容器中创建服务,然后使用extend调用相关的设置器,在此之后插入依赖项。

这是在文档中:Modifying Services after Definition

票数 1
EN

Stack Overflow用户

发布于 2017-03-08 12:23:07

代码语言:javascript
复制
// PIMPLE CONTAINER
use Pimple\Container;
$container = new Container();

use Classes\ClassA;
$container['ClassA'] = function ($c) {
  return new ClassA($c['ClassB']);
};

use Classes\ClassB;
$container['ClassB'] = function ($c) {
  return new ClassB($c);
};

将容器传递给classB,而不是从ClassB实例化ClassA。然后,当您在ClassB中需要ClassA时,您可以使用传递给它的容器来启动/获取ClassA的实例。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42662808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档