diff --git a/CHANGELOG.md b/CHANGELOG.md index e1a24bb..c5d465d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ to [Semantic Versioning](http://semver.org/). ## [unreleased] Unreleased +### Fixed + +- Correctly bind the container to the builders and resolvers when cloning the container. + ## [3.3.6] 2024-04-02; ### Added diff --git a/src/Builders/Factory.php b/src/Builders/Factory.php index 62f7228..75041c8 100644 --- a/src/Builders/Factory.php +++ b/src/Builders/Factory.php @@ -82,4 +82,28 @@ public function getBuilder($id, $implementation = null, array $afterBuildMethods return new ValueBuilder($implementation); } + + /** + * Sets the container the builder should use. + * + * @since TBD + * + * @param Container $container The container to bind. + * + * @return void + */ + public function setContainer( Container $container ) { + $this->container = $container; + } + + /** + * Sets the resolver the container should use. + * + * @since TBD + * + * @param Resolver $resolver The resolver the container should use. + */ + public function setResolver( Resolver $resolver ) { + $this->resolver = $resolver; + } } diff --git a/src/Container.php b/src/Container.php index c7ac788..eea94e6 100644 --- a/src/Container.php +++ b/src/Container.php @@ -916,6 +916,8 @@ public function __clone() { $this->resolver = clone $this->resolver; $this->builders = clone $this->builders; + $this->builders->setContainer($this); + $this->builders->setResolver($this->resolver); $this->bindThis(); } } diff --git a/tests/unit/CloneTest.php b/tests/unit/CloneTest.php index 1f484f3..b1edf55 100644 --- a/tests/unit/CloneTest.php +++ b/tests/unit/CloneTest.php @@ -6,8 +6,28 @@ use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; -class ContainerExtension extends Container -{ +class ContainerExtension extends Container { +} + +class CloneTestFoo { + private $baz; + + public function __construct( CloneTestBazInterface $baz ) { + $this->baz = $baz; + } + + public function getBaz(): CloneTestBazInterface { + return $this->baz; + } +} + +interface CloneTestBazInterface {} + +class CloneTestBazOne implements CloneTestBazInterface { + +} + +class CloneTestBazTwo implements CloneTestBazInterface { } class CloneTest extends TestCase @@ -98,4 +118,32 @@ public function should_bind_the_clone_as_singleton_when_container_class_extended $this->assertSame($clone, $clone->get(ContainerExtension::class)); $this->assertSame($clone, $clone->get(ContainerInterface::class)); } + + /** + * It should use the cloned container to build + * + * @test + */ + public function should_use_the_cloned_container_to_build(): void { + $original = new Container(); + $clone = clone $original; + + $this->assertNotSame( $original, $clone ); + + $original->singleton( CloneTestFoo::class ); + $original->singleton( CloneTestBazInterface::class, CloneTestBazOne::class ); + + $clone->singleton( CloneTestFoo::class ); + $clone->singleton( CloneTestBazInterface::class, CloneTestBazTwo::class ); + + $this->assertNotSame( $original->get( CloneTestFoo::class ), $clone->get( CloneTestFoo::class ) ); + $this->assertNotSame( $original->get( CloneTestBazInterface::class ), + $clone->get( CloneTestBazInterface::class ) ); + $this->assertInstanceOf( CloneTestBazOne::class, $original->get( CloneTestBazInterface::class ) ); + $this->assertInstanceOf( CloneTestBazTwo::class, $clone->get( CloneTestBazInterface::class ) ); + $this->assertInstanceOf( CloneTestBazOne::class, $original->get( CloneTestFoo::class )->getBaz() ); + $this->assertInstanceOf( CloneTestBazTwo::class, $clone->get( CloneTestFoo::class )->getBaz() ); + $this->assertNotSame( $original->get( CloneTestFoo::class )->getBaz(), + $clone->get( CloneTestFoo::class )->getBaz() ); + } }