Garden-Container - setter injection using rule & setClass

Hey guys,

I come up with this little conundrum when I was trying to use setter injection using rule and setClass. I am not sure if I am using the container correctly, if I am missing something or if it's a corner case.

Here is the thing: My expectation is that the following 3 snippets are equivalent code, however, it doesn't seem the case for the last snippet.

Any idea would be appreciated. Thank you.

1 - Snippet works as expected:

$container = new Container();

$container
    ->rule(InjectInterface::class)
    ->addCall('setInjected')
;

/** @var ParentClass $parentClass */
$parentClass = $container->get(ParentClass::class); // ParentClass implements InjectInterface

$this->assertInstanceOf(ParentClass::class, $parentClass);
$this->assertNotNull($parentClass->getInjected());
$this->assertInstanceOf(InjectClass::class, $parentClass->getInjected());

2 - Snippet works as expected:

$alternativeName = 'ParentAlternativeName';
$container = new Container();

$container
    ->rule(InjectInterface::class)
    ->addCall('setInjected')
    //
    ->rule($alternativeName)
    ->setFactory(function () use ($container) {
        return $container->get(ParentClass::class);
    })
    ->setShared(false)
;

/** @var ParentClass $parentClass */
$parentClass = $container->get($alternativeName); // ParentClass implements InjectInterface

$this->assertInstanceOf(ParentClass::class, $parentClass);
$this->assertNotNull($parentClass->getInjected());
$this->assertInstanceOf(InjectClass::class, $parentClass->getInjected());

3 - Snippet doesn't work as expected:

$alternativeName = 'ParentAlternativeName';
$container = new Container();

$container
    ->rule(InjectInterface::class)
    ->addCall('setInjected')
    //
    ->rule($alternativeName)
    ->setClass(ParentClass::class)
    ->setShared(false)
;

/** @var ParentClass $parentClass */
$parentClass = $container->get($alternativeName); // ParentClass implements InjectInterface

$this->assertInstanceOf(ParentClass::class, $parentClass);
$this->assertNotNull($parentClass->getInjected());
$this->assertInstanceOf(InjectClass::class, $parentClass->getInjected());

In this last case, I get an instance of ParentClass but the injected dependency is null, which would means that the setter is never called.

If you want to dig a little bit on this, I prepared a testCase in a new branch.

git clone --single-branch --branch test/setterInjection git@github.com:vanilla/garden-container.git
cd garden-container 
composer install
./vendor/bin/phpunit


Comments