From bfb35e8459685b8d955030621b79553069ff3600 Mon Sep 17 00:00:00 2001 From: Luca Tumedei Date: Fri, 26 Apr 2024 16:07:49 +0200 Subject: [PATCH] fix(Container) bind container and resolver correctly in clone --- CHANGELOG.md | 4 +++ src/Builders/Factory.php | 28 ++++++++++++++++++ src/Container.php | 2 ++ tests/unit/CloneTest.php | 61 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+) 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..6c25773 100644 --- a/src/Builders/Factory.php +++ b/src/Builders/Factory.php @@ -82,4 +82,32 @@ 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. + * + * @return void + */ + public function setResolver(Resolver $resolver) + { + $this->resolver = $resolver; + } } diff --git a/src/Container.php b/src/Container.php index c7ac788..84f3e38 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..1921260 100644 --- a/tests/unit/CloneTest.php +++ b/tests/unit/CloneTest.php @@ -10,6 +10,34 @@ class ContainerExtension extends Container { } +class CloneTestFoo +{ + private $baz; + + public function __construct(CloneTestBazInterface $baz) + { + $this->baz = $baz; + } + + public function getBaz() + { + return $this->baz; + } +} + +interface CloneTestBazInterface +{ +} + +class CloneTestBazOne implements CloneTestBazInterface +{ + +} + +class CloneTestBazTwo implements CloneTestBazInterface +{ +} + class CloneTest extends TestCase { /** @@ -98,4 +126,37 @@ 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() + { + $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() + ); + } }