微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 循环依赖 – 注入直接相互依赖的对象

我已经使用了Dice PHP DI container很长一段时间,它在注入依赖项的简单性方面似乎是最好的.

Dice Documentation开始:

class A {
    public $b;

    public function __construct(B $b) {
        $this->b = $b;
    }
}

class B {

}

$dice = new \Dice\Dice;    
$a = $dice->create('A');
var_dump($a->b); //B object

但是,当您必须使用直接相互依赖的对象时,由于无限循环,finall结果是服务器错误.

例:

class A {
    public $b;

    public function __construct(B $b) {
        $this->b = $b;
    }
}

class B {
    public $a;

    public function __construct(A $a) {
        $this->a = $a;
    }
}

Dice的作者说没有办法从A或B类构造一个对象.如:

>’A’对象需要’B’对象才能创建
>但是’B’对象需要’A’对象才能创建

作者说,这个限制涉及所有DI容器!

题:

在不改变初始代码的情况下,很好地克服这个问题的最佳解决方案是什么?任何人都可以提供一个使用其他DI容器的例子,什么时候可以运行exampled代码而不需要庞大的解决方法

解决方法:

正如您在Dice github(https://github.com/TomBZombie/Dice/issues/7)上的帖子中所提到的,在不删除循环依赖的情况下解决的唯一方法是重构其中一个类以使用setter注入:

class A {
    public $b;

    public function __construct(B $b) {
        $this->b = $b;
    }
}


class B {
    public $a;

    public function setA(A $a) {
        $this->a = $a;
    }
}

这允许构造对象:

$b = new B();
$a = new A($b);
$b->setA($a);

使用原始代码

class A {
    public $b;

    public function __construct(B $b) {
        $this->b = $b;
    }
}

class B {
    public $a;

    public function __construct(A $a) {
        $this->a = $a;
    }
}

您无法构造它并遇到与容器相同的问题:

$b = new B(new A(new B(new A(new B(.............))))

使用诸如ReflectionClass :: newInstanceWithoutConstructor之类的hack使容器解决此问题的问题是您的对象现在依赖于使用此方法的创建逻辑.您基本上将代码耦合到容器,这是一个糟糕的设计,因为您的代码现在不再是可移植的,并且不能在没有容器的情况下使用它来执行对象构造.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐