From ea318fc5efb8823d170d49e357fbd7f196162d50 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sun, 4 Feb 2024 23:21:07 +0100 Subject: [PATCH] FactoryDefinition: result definition is added to container [WIP] --- src/DI/Definitions/FactoryDefinition.php | 5 +++++ src/DI/Extensions/DecoratorExtension.php | 18 ++---------------- src/DI/Extensions/InjectExtension.php | 9 ++------- src/DI/Extensions/ServicesExtension.php | 2 +- tests/DI/DecoratorExtension.factories.phpt | 16 ++++++++-------- tests/SearchExtension/all.phpt | 1 + tests/SearchExtension/batches.phpt | 1 + tests/SearchExtension/classes.phpt | 3 +++ tests/SearchExtension/duplicates.phpt | 1 + tests/SearchExtension/files.phpt | 4 ++++ tests/SearchExtension/parents.phpt | 2 ++ tests/SearchExtension/tags.phpt | 2 ++ 12 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/DI/Definitions/FactoryDefinition.php b/src/DI/Definitions/FactoryDefinition.php index 7c2e69caa..ff5e6c537 100644 --- a/src/DI/Definitions/FactoryDefinition.php +++ b/src/DI/Definitions/FactoryDefinition.php @@ -24,6 +24,7 @@ final class FactoryDefinition extends Definition private const MethodCreate = 'create'; private Definition $resultDefinition; + private ?string $reference = null; public function __construct() @@ -87,6 +88,10 @@ public function resolveType(Nette\DI\Resolver $resolver): void { if (!$this->getType()) { throw new ServiceCreationException('Type is missing in definition of service.'); + + } elseif ($this->reference === null) { + $this->resultDefinition->setAutowired(false); + $this->reference = $resolver->getContainerBuilder()->addDefinition(null, $this->resultDefinition)->getName(); } $type = Type::fromReflection(new \ReflectionMethod($this->getType(), self::MethodCreate)); diff --git a/src/DI/Extensions/DecoratorExtension.php b/src/DI/Extensions/DecoratorExtension.php index 7afa70339..1c2f132dd 100644 --- a/src/DI/Extensions/DecoratorExtension.php +++ b/src/DI/Extensions/DecoratorExtension.php @@ -50,11 +50,7 @@ public function beforeCompile() public function addSetups(string $type, array $setups): void { - foreach ($this->findByType($type) as $def) { - if ($def instanceof Definitions\FactoryDefinition) { - $def = $def->getResultDefinition(); - } - + foreach ($this->getContainerBuilder()->findByType($type) as $def) { foreach ($setups as $setup) { if (is_array($setup)) { $setup = new Definitions\Statement(key($setup), array_values($setup)); @@ -69,18 +65,8 @@ public function addSetups(string $type, array $setups): void public function addTags(string $type, array $tags): void { $tags = Nette\Utils\Arrays::normalize($tags, filling: true); - foreach ($this->findByType($type) as $def) { + foreach ($this->getContainerBuilder()->findByType($type) as $def) { $def->setTags($def->getTags() + $tags); } } - - - private function findByType(string $type): array - { - return array_filter( - $this->getContainerBuilder()->getDefinitions(), - fn(Definitions\Definition $def): bool => is_a($def->getType(), $type, true) - || ($def instanceof Definitions\FactoryDefinition && is_a($def->getResultType(), $type, allow_string: true)), - ); - } } diff --git a/src/DI/Extensions/InjectExtension.php b/src/DI/Extensions/InjectExtension.php index 91948615f..b268b4f4c 100644 --- a/src/DI/Extensions/InjectExtension.php +++ b/src/DI/Extensions/InjectExtension.php @@ -35,13 +35,8 @@ public function getConfigSchema(): Nette\Schema\Schema public function beforeCompile() { foreach ($this->getContainerBuilder()->getDefinitions() as $def) { - if ($def->getTag(self::TagInject)) { - $def = $def instanceof Definitions\FactoryDefinition - ? $def->getResultDefinition() - : $def; - if ($def instanceof Definitions\ServiceDefinition) { - $this->updateDefinition($def); - } + if ($def instanceof Definitions\ServiceDefinition && $def->getTag(self::TagInject)) { + $this->updateDefinition($def); } } } diff --git a/src/DI/Extensions/ServicesExtension.php b/src/DI/Extensions/ServicesExtension.php index 8bb50257d..38ab845be 100644 --- a/src/DI/Extensions/ServicesExtension.php +++ b/src/DI/Extensions/ServicesExtension.php @@ -169,7 +169,7 @@ private function updateFactoryDefinition(Definitions\FactoryDefinition $definiti } if (isset($config->inject)) { - $definition->addTag(InjectExtension::TagInject, $config->inject); + $resultDef->addTag(InjectExtension::TagInject, $config->inject); } } diff --git a/tests/DI/DecoratorExtension.factories.phpt b/tests/DI/DecoratorExtension.factories.phpt index ba99a41dc..6b9b2e92a 100644 --- a/tests/DI/DecoratorExtension.factories.phpt +++ b/tests/DI/DecoratorExtension.factories.phpt @@ -30,7 +30,7 @@ $compiler->addExtension('foo', new class extends DI\CompilerExtension { public function beforeCompile() { $this->getContainerBuilder() - ->addFactoryDefinition('bar') + ->addFactoryDefinition('fac1') ->setImplement(FooFactory::class); } }); @@ -45,16 +45,16 @@ decorator: FooFactory: tags: [a] services: - foo: {implement: FooFactory} + fac2: {implement: FooFactory} '); $builder = $compiler->getContainerBuilder(); -Assert::true($builder->getDefinition('foo')->getTag(DI\Extensions\InjectExtension::TagInject)); -Assert::true($builder->getDefinition('foo')->getTag('a')); -Assert::count(1, $builder->getDefinition('foo')->getResultDefinition()->getSetup()); +Assert::true($builder->getDefinition('fac1')->getTag('a')); +Assert::count(1, $builder->getDefinition('fac1')->getResultDefinition()->getSetup()); +Assert::true($builder->getDefinition('fac1')->getResultDefinition()->getTag(DI\Extensions\InjectExtension::TagInject)); -Assert::true($builder->getDefinition('bar')->getTag(DI\Extensions\InjectExtension::TagInject)); -Assert::true($builder->getDefinition('bar')->getTag('a')); -Assert::count(1, $builder->getDefinition('bar')->getResultDefinition()->getSetup()); +Assert::true($builder->getDefinition('fac2')->getTag('a')); +Assert::count(1, $builder->getDefinition('fac2')->getResultDefinition()->getSetup()); +Assert::true($builder->getDefinition('fac2')->getResultDefinition()->getTag(DI\Extensions\InjectExtension::TagInject)); diff --git a/tests/SearchExtension/all.phpt b/tests/SearchExtension/all.phpt index f2d066d9f..a950d7742 100644 --- a/tests/SearchExtension/all.phpt +++ b/tests/SearchExtension/all.phpt @@ -22,6 +22,7 @@ Assert::same([ 'Foo\\ClassBar', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); diff --git a/tests/SearchExtension/batches.phpt b/tests/SearchExtension/batches.phpt index 26fda917b..4e4ac6d44 100644 --- a/tests/SearchExtension/batches.phpt +++ b/tests/SearchExtension/batches.phpt @@ -37,4 +37,5 @@ Assert::same([ 'Foo\\ClassBar' => ['foo' => true], 'InterfaceOk1' => ['ok' => true], 'InterfaceOk2' => ['ok' => true], + 'stdClass' => [], ], $services); diff --git a/tests/SearchExtension/classes.phpt b/tests/SearchExtension/classes.phpt index cea9cfac7..4d21f9087 100644 --- a/tests/SearchExtension/classes.phpt +++ b/tests/SearchExtension/classes.phpt @@ -23,6 +23,7 @@ Assert::same([ 'Foo\\ClassBar', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); @@ -53,6 +54,7 @@ Assert::same([ 'Foo\\ClassBar', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); @@ -102,4 +104,5 @@ Assert::same([ 'ExtendsStdClass', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); diff --git a/tests/SearchExtension/duplicates.phpt b/tests/SearchExtension/duplicates.phpt index d8b2eec98..c52f03a71 100644 --- a/tests/SearchExtension/duplicates.phpt +++ b/tests/SearchExtension/duplicates.phpt @@ -28,4 +28,5 @@ Assert::same([ 'Foo\\ClassBar', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); diff --git a/tests/SearchExtension/files.phpt b/tests/SearchExtension/files.phpt index b72a55147..3fdea3b07 100644 --- a/tests/SearchExtension/files.phpt +++ b/tests/SearchExtension/files.phpt @@ -23,6 +23,7 @@ Assert::same([ 'Foo\\ClassBar', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); @@ -41,6 +42,7 @@ Assert::same([ 'ExtendsStdClass', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); @@ -63,6 +65,7 @@ Assert::same([ 'Foo\\ClassBar', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); @@ -83,4 +86,5 @@ Assert::same([ 'ExtendsStdClass', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); diff --git a/tests/SearchExtension/parents.phpt b/tests/SearchExtension/parents.phpt index bf8bf1254..c36fb78f2 100644 --- a/tests/SearchExtension/parents.phpt +++ b/tests/SearchExtension/parents.phpt @@ -23,6 +23,7 @@ Assert::same([ 'Foo\\ClassBar', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); @@ -99,4 +100,5 @@ Assert::same([ 'Foo\\ClassBar', 'InterfaceOk1', 'InterfaceOk2', + 'stdClass', ], array_keys($services)); diff --git a/tests/SearchExtension/tags.phpt b/tests/SearchExtension/tags.phpt index 7c2002658..6064d0be1 100644 --- a/tests/SearchExtension/tags.phpt +++ b/tests/SearchExtension/tags.phpt @@ -24,6 +24,7 @@ Assert::same([ 'ExtendsStdClass' => ['a' => 1, 'b' => 2], 'InterfaceOk1' => ['a' => 1, 'b' => 2], 'InterfaceOk2' => ['a' => 1, 'b' => 2], + 'stdClass' => [], ], $services); @@ -43,4 +44,5 @@ Assert::same([ 'ExtendsStdClass' => [], 'InterfaceOk1' => [], 'InterfaceOk2' => [], + 'stdClass' => [], ], $services);