Circular reference exception

6 years ago

erani
Member | 6
+
0
-

Hello,

who knows, how to solve the circular reference in nette?

I have the following setup, as example:

services:
    modelA:
        class: ModelA
        setup:
            - setModelB(@modelB)

    modelB:
        class: ModelB
        setup:
            - setModelA(@modelA)

I understand to get the exception in case I will configure the dependency by constructor, but here is by setters, why it is done in that way?

Is there any way to solve this without breaking the DI principle?

Thank you.

Last edited by erani (2014-01-23 22:53)

6 years ago

mkoubik
Generous Backer | 734
+
0
-
class ModelABFactory
{
    private $modelA;
    private $modelB;

    public function getModelA()
    {
        if ($this->modelA === null) {
            $this->modelA = new ModelA();
            $this->modelB = new ModelB();
            $this->modelA->setModelB($this->modelB);
            $this->modelB->setModelA($this->modelA);
        }
        return $this->modelA;
    }

    public function getModelB()
    {
        // ...
    }
}
services:
    modelABFactory: ModelABFactory
    modelA: @modelABFactory::getModelA()
    modelB: @modelABFactory::getModelB()

Last edited by mkoubik (2014-01-24 00:09)

6 years ago

erani
Member | 6
+
0
-

Yes it is a solution, thank you, but if there is a case where you have more such links between services, will get to the point that you will make a lot of that kind of factories, or just extend the container and will solve there the link problem.

I was looking into the code, and found that if when the method for service creation is compiled, after the service instance is create will be registered in registry and then the process of setter will run, that can fix the issue with circular reference.

I would like to hear others what they think about.

Thank you.

6 years ago

duke
Member | 650
+
0
-

Separation of registering phase and setup phase would solve problem with circular referencing in setup phase, but it would introduce a problem of allowing non-initialized services being passed around.

Maybe we could add another (post-setup) phase where those setters could be called, but I am not sure it's necessary.

Last edited by duke (2014-01-24 14:04)

6 years ago

Filip Procházka
Moderator | 4693
+
0
-

This is a signal, that you must create third model, that contains modelA and modelB and does what require each other for.