diff --git a/CHANGELOG.md b/CHANGELOG.md index be57fd623..579ef596e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Added - [#317](https://github.com/hyperf-cloud/hyperf/pull/317) Added composer-json-fixer and Optimized composer.json. @[wenbinye](https://github.com/wenbinye) +- [#320](https://github.com/hyperf-cloud/hyperf/pull/320) DI added support for closure definition. ## Fixed diff --git a/src/di/src/Definition/DefinitionSource.php b/src/di/src/Definition/DefinitionSource.php index c6c2f4f7e..2a624bcce 100644 --- a/src/di/src/Definition/DefinitionSource.php +++ b/src/di/src/Definition/DefinitionSource.php @@ -32,7 +32,6 @@ use function filemtime; use function fopen; use function implode; use function interface_exists; -use function is_array; use function is_callable; use function is_dir; use function is_readable; @@ -97,9 +96,12 @@ class DefinitionSource implements DefinitionSourceInterface return $this->source; } - public function addDefinition(string $name, array $definition): self + /** + * @param array|string|callable $definition + */ + public function addDefinition(string $name, $definition): self { - $this->source[$name] = $definition; + $this->source[$name] = $this->normalizeDefinition($name, $definition); return $this; } @@ -138,19 +140,31 @@ class DefinitionSource implements DefinitionSourceInterface { $definitions = []; foreach ($source as $identifier => $definition) { - if (is_string($definition) && class_exists($definition)) { - if (method_exists($definition, '__invoke')) { - $definitions[$identifier] = new FactoryDefinition($identifier, $definition, []); - } else { - $definitions[$identifier] = $this->autowire($identifier, new ObjectDefinition($identifier, $definition)); - } - } elseif (is_array($definition) && is_callable($definition)) { - $definitions[$identifier] = new FactoryDefinition($identifier, $definition, []); + $normalizedDefinition = $this->normalizeDefinition($identifier, $definition); + if (! is_null($normalizedDefinition)) { + $definitions[$identifier] = $normalizedDefinition; } } return $definitions; } + /** + * @param array|string|callable $definitions + */ + private function normalizeDefinition(string $identifier, $definition): ?DefinitionInterface + { + if (is_string($definition) && class_exists($definition)) { + if (method_exists($definition, '__invoke')) { + return new FactoryDefinition($identifier, $definition, []); + } + return $this->autowire($identifier, new ObjectDefinition($identifier, $definition)); + } + if (is_callable($definition)) { + return new FactoryDefinition($identifier, $definition, []); + } + return null; + } + private function autowire(string $name, ObjectDefinition $definition = null): ?ObjectDefinition { $className = $definition ? $definition->getClassName() : $name; diff --git a/src/di/src/Definition/DefinitionSourceInterface.php b/src/di/src/Definition/DefinitionSourceInterface.php index b80ce70fa..03bcd2078 100644 --- a/src/di/src/Definition/DefinitionSourceInterface.php +++ b/src/di/src/Definition/DefinitionSourceInterface.php @@ -30,9 +30,10 @@ interface DefinitionSourceInterface public function getDefinitions(): array; /** + * @param mixed $definition * @return $this */ - public function addDefinition(string $name, array $definition); + public function addDefinition(string $name, $definition); public function clearDefinitions(): void; } diff --git a/src/di/tests/DefinitionSourceTest.php b/src/di/tests/DefinitionSourceTest.php new file mode 100644 index 000000000..6630ca941 --- /dev/null +++ b/src/di/tests/DefinitionSourceTest.php @@ -0,0 +1,34 @@ +getDefinitionSource()->addDefinition('Foo', function () { + return 'bar'; + }); + $this->assertEquals('bar', $container->get('Foo')); + } +}