From 742879e674ff0548df546e0fdd87c42e163312c3 Mon Sep 17 00:00:00 2001 From: "as2252258@163.com" Date: Tue, 23 Feb 2021 03:17:32 +0800 Subject: [PATCH] modify --- System/Di/Container.php | 176 +++++++++++++++++----------------------- System/Di/Service.php | 48 +++++------ 2 files changed, 101 insertions(+), 123 deletions(-) diff --git a/System/Di/Container.php b/System/Di/Container.php index cb911324..7df1f5b5 100644 --- a/System/Di/Container.php +++ b/System/Di/Container.php @@ -9,13 +9,10 @@ declare(strict_types=1); namespace Snowflake\Di; -use Database\Connection; -use HttpServer\Http\HttpHeaders; use ReflectionClass; use Snowflake\Abstracts\BaseObject; use ReflectionException; use Snowflake\Exception\NotFindClassException; -use Snowflake\Snowflake; /** * Class Container @@ -29,28 +26,29 @@ class Container extends BaseObject * * instance class by className */ - private array $_singletons = []; + private $_singletons = []; /** * @var array * * class new instance construct parameter */ - private array $_constructs = []; + private $_constructs = []; /** * @var array * * implements \ReflectClass */ - private array $_reflection = []; + private $_reflection = []; /** * @var array * * The construct parameter */ - private array $_param = []; + private $_param = []; + /** * @param $class @@ -61,73 +59,91 @@ class Container extends BaseObject * @throws NotFindClassException * @throws ReflectionException */ - public function get($class, $constrict = [], $config = []): mixed + public function get($class, $constrict = [], $config = []) { if (isset($this->_singletons[$class])) { return $this->_singletons[$class]; - } - if (!isset($this->_constructs[$class])) { + } else if (!isset($this->_constructs[$class])) { return $this->resolve($class, $constrict, $config); } - - $definition = $this->_param[$class] ?? ['class' => $class]; + $definition = $this->_constructs[$class]; if (is_callable($definition, TRUE)) { return call_user_func($definition, $this, $constrict, $config); } else if (is_array($definition)) { - $constructs = $this->_constructs[$class] ?? []; - if ($class === $definition['class']) { - $object = $this->resolve($class, $constructs, $config); - } else { - $object = $this->get($class, $constructs, $config); - } - return $this->_singletons[$class] = $object; + $object = $this->resolveDefinition($definition, $class, $config, $constrict); } else if (is_object($definition)) { return $this->_singletons[$class] = $definition; } else { throw new NotFindClassException($class); } + return $this->_singletons[$class] = $object; } + /** + * @param $definition + * @param $class + * @param $config + * @param $constrict + * @return mixed + * @throws NotFindClassException + * @throws ReflectionException + */ + private function resolveDefinition($definition, $class, $config, $constrict) + { + if (!isset($definition['class'])) { + throw new NotFindClassException($class); + } + $_className = $definition['class']; + unset($definition['class']); + + $config = array_merge($definition, $config); + $definition = $this->mergeParam($class, $constrict); + + if ($_className === $class) { + $object = $this->resolve($class, $definition, $config); + } else { + $object = $this->get($class, $definition, $config); + } + return $object; + } /** * @param $class * @param $constrict * @param $config * - * @return object + * @return mixed * @throws NotFindClassException * @throws ReflectionException */ - private function resolve($class, $constrict, $config): object + private function resolve($class, $constrict, $config) { - $reflect = $this->resolveDependencies($class, $constrict); + /** + * @var ReflectionClass $reflect + * @var array $dependencies + */ + list($reflect, $dependencies) = $this->resolveDependencies($class); + foreach ($constrict as $index => $param) { + $dependencies[$index] = $param; + } if (!$reflect->isInstantiable()) { throw new NotFindClassException($reflect->getName()); } - $this->_param[$class] = $config; - $this->_param[$class]['class'] = $class; - - $dependencies = $this->_constructs[$class] ?? []; if (empty($config)) { - return $reflect->newInstanceArgs($dependencies); + return $reflect->newInstanceArgs($dependencies ?? []); } - if (!empty($dependencies) && $reflect->implementsInterface('Snowflake\Abstracts\Configure')) { + if (!empty($dependencies) && $reflect->implementsInterface('BeReborn\Base\Configure')) { $dependencies[count($dependencies) - 1] = $config; return $reflect->newInstanceArgs($dependencies); } - - return $this->onAfterInit($reflect->newInstanceArgs($dependencies), $config); - } - - /** - * @param $object - * @param $config - * @return mixed - */ - private function onAfterInit($object, $config) - { - Snowflake::configure($object, $config); + if (!empty($config)) { + $this->_param[$class] = $config; + } + $object = $reflect->newInstanceArgs($dependencies ?? []); + foreach ($config as $key => $val) { + $object->{$key} = $val; + } if (method_exists($object, 'afterInit')) { call_user_func([$object, 'afterInit']); } @@ -140,71 +156,31 @@ class Container extends BaseObject * @return array * @throws ReflectionException */ - private function resolveDependencies($class, $constrict = []): ?ReflectionClass + private function resolveDependencies($class) { - if (!isset($this->_reflection[$class])) { - $reflection = new ReflectionClass($class); - if (!$reflection->isInstantiable()) { - return null; - } - $this->_reflection[$class] = $reflection; - } else { + $dependencies = []; + if (isset($this->_reflection[$class])) { $reflection = $this->_reflection[$class]; - } - - if (!is_null($construct = $reflection->getConstructor())) { - $this->_constructs[$class] = $this->resolveMethodParam($construct, $constrict); } else { - $this->_constructs[$class] = $constrict; + $reflection = new ReflectionClass($class); + $this->_reflection[$class] = $reflection; } - return $reflection; - } - - - /** - * @param \ReflectionMethod|null $method - * @return array - * @throws NotFindClassException - * @throws ReflectionException - */ - private function resolveMethodParam(?\ReflectionMethod $method, $default = []): array - { - $array = []; - foreach ($method->getParameters() as $key => $parameter) { - if (!is_null($default[$key] ?? null)) { - $array[] = $default[$key]; - } else if ($parameter->isDefaultValueAvailable()) { - $array[] = $parameter->getDefaultValue(); + $constructs = $reflection->getConstructor(); + if (empty($constructs) || !is_array($constructs)) { + return [$reflection, []]; + } + foreach ($constructs->getParameters() as $key => $param) { + if (version_compare(PHP_VERSION, '5.6.0', '>=') && $param->isVariadic()) { + break; + } else if ($param->isDefaultValueAvailable()) { + $dependencies[] = $param->getDefaultValue(); } else { - $type = $parameter->getType(); - if (is_string($type) && class_exists($type)) { - $type = Snowflake::createObject($type); - } - $array[] = match ($parameter->getType()) { - 'string' => '', - 'int', 'float' => 0, - '', null, 'object', 'mixed' => NULL, - 'bool' => false, - default => $type - }; + $c = $param->getClass(); + $dependencies[] = $c === NULL ? NULL : $c->getName(); } } - return $array; - } - - - /** - * @param $class - * @return mixed - * @throws ReflectionException - */ - public function getReflect($class): ?ReflectionClass - { - $reflect = $this->_reflection[$class] ?? null; - if (!is_null($reflect)) { - return $reflect; - } - return $this->resolveDependencies($class); + $this->_constructs[$class] = $dependencies; + return [$reflection, $dependencies]; } /** @@ -226,7 +202,7 @@ class Container extends BaseObject /** * @return $this */ - public function flush(): static + public function flush() { $this->_reflection = []; $this->_singletons = []; @@ -241,7 +217,7 @@ class Container extends BaseObject * * @return mixed */ - private function mergeParam($class, $newParam): array + private function mergeParam($class, $newParam) { if (empty($this->_param[$class])) { return $newParam; diff --git a/System/Di/Service.php b/System/Di/Service.php index 313c1821..9b36ec0c 100644 --- a/System/Di/Service.php +++ b/System/Di/Service.php @@ -40,24 +40,21 @@ class Service extends Component */ public function get($id): mixed { - if (isset($this->_components[$id])) { - return $this->_components[$id]; - } - if (!isset($this->_definition[$id]) && !isset($this->_alias[$id])) { - throw new ComponentException("Unknown component ID: $id"); - } - if (isset($this->_definition[$id])) { + if (!isset($this->_components[$id])) { + if (!isset($this->_definition[$id])) { + throw new ComponentException("Unknown component ID: $id"); + } $config = $this->_definition[$id]; if (is_object($config)) { - return $this->_components[$id] = $config; + return $config; } - $object = Snowflake::createObject($config); - } else { - $config = $this->_alias[$id]; - - $object = Snowflake::createObject($config); + $this->_components[$id] = Snowflake::createObject($config); } - return $this->_components[$id] = Snowflake::configure($object, $config); + $object = $this->_components[$id]; + if (method_exists($object, 'afterInit')) { + $object->afterInit(); + } + return $object; } /** @@ -81,20 +78,25 @@ class Service extends Component public function set($id, $definition): mixed { if ($definition === NULL) { - return $this->remove($id); + $this->remove($id); + return; } + unset($this->_components[$id]); + if (is_object($definition) || is_callable($definition, TRUE)) { - return $this->_definition[$id] = $definition; - } else if (!is_array($definition)) { + $this->_definition[$id] = $definition; + return; + } else if (is_array($definition)) { + if (isset($definition['class'])) { + $this->_definition[$id] = $definition; + } else { + throw new ComponentException("The configuration for the \"$id\" component must contain a \"class\" element."); + } + } else { throw new ComponentException("Unexpected configuration type for the \"$id\" component: " . gettype($definition)); } - if (!isset($definition['class'])) { - throw new ComponentException("The configuration for the \"$id\" component must contain a \"class\" element."); - } else { - $this->_definition[$id] = $definition; - } - return $this->get($id); + $this->_components[$id] = $object = Snowflake::createObject($definition); } /**