Circular dependency - Injecting objects that are directly depended on each other

后端 未结 2 1741
刺人心
刺人心 2021-01-11 13:57

I have used Dice PHP DI container for quite a while and it seems the best in terms of simplicity of injecting dependencies.

From Dice Documentation:

cl         


        
2条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-11 14:26

    As mentioned on your post on the Dice github ( https://github.com/TomBZombie/Dice/issues/7 ), the only way to resolve without removing the circular dependency is to refactor one of the classes to use setter injection:

    class A {
        public $b;
    
        public function __construct(B $b) {
            $this->b = $b;
        }
    }
    
    
    class B {
        public $a;
    
        public function setA(A $a) {
            $this->a = $a;
        }
    }
    

    This allows the objects to be constructed:

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

    With the original code:

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

    You cannot construct it and run into the same problem as the container:

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

    The problem with having a container work around this issue using a hack such as ReflectionClass::newInstanceWithoutConstructor is that your objects are now dependent on creation logic which uses this method. You essentially couple the code to the container which is a poor design as your code is now no longer portable and cannot be used without the container to perform the object construction.

提交回复
热议问题