diff --git a/CHANGELOG.md b/CHANGELOG.md index 1539c96c..9e50cefe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.2.1 under development -- no changes in this release. +- Bug #317: Fix delegated container (@xepozz) ## 1.2.0 November 05, 2022 diff --git a/src/Container.php b/src/Container.php index 512c9482..984f0e6c 100644 --- a/src/Container.php +++ b/src/Container.php @@ -247,6 +247,8 @@ private function addDefinitions(array $config): void private function setDelegates(array $delegates): void { $this->delegates = new CompositeContainer(); + $container = $this->get(ContainerInterface::class); + foreach ($delegates as $delegate) { if (!$delegate instanceof Closure) { throw new InvalidConfigException( @@ -255,7 +257,7 @@ private function setDelegates(array $delegates): void } /** @var ContainerInterface */ - $delegate = $delegate($this); + $delegate = $delegate($container); if (!$delegate instanceof ContainerInterface) { throw new InvalidConfigException( diff --git a/tests/Unit/ContainerTest.php b/tests/Unit/ContainerTest.php index 8a29b2f2..901f5b73 100644 --- a/tests/Unit/ContainerTest.php +++ b/tests/Unit/ContainerTest.php @@ -1235,6 +1235,34 @@ static function (ContainerInterface $container) { $this->assertSame(42, $engine->getNumber()); } + public function testNewContainerDefinitionInDelegates(): void + { + $firstContainer = null; + $secondContainer = null; + + $config = ContainerConfig::create() + ->withDefinitions([ + ContainerInterface::class => new Container(ContainerConfig::create()), + ]) + ->withDelegates([ + function (ContainerInterface $container) use (&$firstContainer): ContainerInterface { + $firstContainer = $container; + return new Container(ContainerConfig::create()); + }, + function (ContainerInterface $container) use (&$secondContainer): ContainerInterface { + $secondContainer = $container; + return new Container(ContainerConfig::create()); + }, + ]); + $originalContainer = new Container($config); + + $container = $originalContainer->get(ContainerInterface::class); + + $this->assertNotSame($container, $originalContainer); + $this->assertSame($container, $firstContainer); + $this->assertSame($container, $secondContainer); + } + public function testResetterInDelegatesWithCustomResetter(): void { $config = ContainerConfig::create() @@ -1593,6 +1621,31 @@ public function getExtensions(): array $container->get(B::class); } + public function testDifferentContainerWithProviders(): void + { + $provider = new class () implements ServiceProviderInterface { + public function getDefinitions(): array + { + return [ + ContainerInterface::class => static fn (ContainerInterface $container) => new Container(ContainerConfig::create()), + ]; + } + + public function getExtensions(): array + { + return []; + } + }; + + $config = ContainerConfig::create() + ->withProviders([$provider]); + $originalContainer = new Container($config); + + $container = $originalContainer->get(ContainerInterface::class); + + $this->assertNotSame($originalContainer, $container); + } + public function testErrorOnMethodTypo(): void { $this->expectException(InvalidConfigException::class);