Merge pull request #320 from wenbinye/feature-di-add-definition

support add definition runtime, support closure as factory definition
This commit is contained in:
李铭昕 2019-08-02 11:42:48 +08:00 committed by GitHub
commit 876dc41161
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 12 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\Di;
use Hyperf\Di\Annotation\Scanner;
use Hyperf\Di\Container;
use Hyperf\Di\Definition\DefinitionSource;
use PHPUnit\Framework\TestCase;
/**
* @internal
* @coversNothing
*/
class DefinitionSourceTest extends TestCase
{
public function testAddDefinition()
{
$container = new Container(new DefinitionSource([], [], new Scanner()));
$container->getDefinitionSource()->addDefinition('Foo', function () {
return 'bar';
});
$this->assertEquals('bar', $container->get('Foo'));
}
}