From 73084a631ff4d6def7475b3169584c0602f9ddce Mon Sep 17 00:00:00 2001 From: Sleon4 Date: Fri, 19 Jan 2024 17:31:30 -0500 Subject: [PATCH] feat: support for dependency injection by parameters or default parameters has been extended --- src/DependencyInjection/Container.php | 35 ++++++++++------ tests/ContainerTest.php | 60 +++++++++++++++++++++------ tests/Provider/CustomClass.php | 10 +++++ tests/Provider/FactoryProvider.php | 13 ++++++ 4 files changed, 93 insertions(+), 25 deletions(-) diff --git a/src/DependencyInjection/Container.php b/src/DependencyInjection/Container.php index 816feb6..6a27526 100644 --- a/src/DependencyInjection/Container.php +++ b/src/DependencyInjection/Container.php @@ -42,38 +42,47 @@ public function getFiles(string $folder): array return $files; } - public function getNamespace(string $file, string $namespace, string $split): string + public function getNamespace(string $file, string $namespace, string $split = '/'): string { $splitFile = explode($split, $file); return $this->str->of("{$namespace}{$splitFile[1]}")->replace("/", "\\")->replace('.php', '')->trim()->get(); } - private function getParameters(ReflectionMethod $method): array + private function getParameters(ReflectionMethod $method, array $params = []): array { - return array_map( - fn($parameter) => $this->container->get($this->getParameterClassName($parameter)), - $method->getParameters() - ); + $args = []; + + foreach ($method->getParameters() as $parameter) { + if ($parameter->isDefaultValueAvailable()) { + $args[] = $parameter->getDefaultValue(); + } else { + if (!empty($params[$parameter->getName()])) { + $args[] = $params[$parameter->getName()]; + } else { + $args[] = $this->container->get($this->getParameterClassName($parameter)); + } + } + } + + return $args; } - public function injectDependenciesMethod(object $object, string $method): mixed + public function injectDependenciesMethod(object $object, string $method, array $params = []): mixed { $method = (new ReflectionClass($object))->getMethod($method); - return $method->invoke($object, ...$this->getParameters($method)); + return $method->invoke($object, ...$this->getParameters($method, $params)); } - public function injectDependencies(object $object): object + public function injectDependencies(object $object, array $params = []): object { - $reflectionClass = new ReflectionClass($object); - - foreach ($reflectionClass->getMethods() as $method) { + foreach ((new ReflectionClass($object))->getMethods() as $method) { $docDocument = $method->getDocComment(); if (is_string($docDocument)) { if ((bool) preg_match('/@required/', $docDocument)) { - $method->invoke($object, ...$this->getParameters($method)); + $method->invoke($object, ...$this->getParameters($method, $params)); } } } diff --git a/tests/ContainerTest.php b/tests/ContainerTest.php index 7cadf03..ea15638 100644 --- a/tests/ContainerTest.php +++ b/tests/ContainerTest.php @@ -15,6 +15,7 @@ class ContainerTest extends Test { + const STR = 'test'; const FOLDER = './tests/'; const PATH_FILE = './Provider/CustomClass.php'; const FILES = [ @@ -59,24 +60,57 @@ public function testGetNamespace(): void public function testGetParameters(): void { - $class = new class { - public function exampleMethod(FactoryProvider $factoryProvider): FactoryProvider - { - return $factoryProvider; - } - }; - - $parameters = $this->getPrivateMethod('getParameters', [new ReflectionMethod($class, 'exampleMethod')]); + $parameters = $this->getPrivateMethod( + 'getParameters', + [new ReflectionMethod(new CustomClass(), 'setFactoryProvider') + ]); $this->assertIsArray($parameters); $this->assertInstanceOf(FactoryProvider::class, reset($parameters)); + + $parameters = $this->getPrivateMethod( + 'getParameters', + [new ReflectionMethod(new CustomClass(), 'setMultiple') + ]); + + $this->assertIsArray($parameters); + + $first = reset($parameters); + $second = end($parameters); + + $this->assertInstanceOf(FactoryProvider::class, $first); + $this->assertIsString($second); + $this->assertSame(self::STR, $second); } public function testInjectDependenciesMethod(): void { - $returnValue = $this->container->injectDependenciesMethod($this->customClass, 'setFactoryProviderSecond'); + /** @var FactoryProvider $factoryProvider */ + $factoryProvider = $this->container->injectDependenciesMethod($this->customClass, 'setFactoryProviderSecond'); + + $this->assertInstanceOf(FactoryProvider::class, $factoryProvider); + } + + public function testInjectDependenciesMethodWithMultipleArguments(): void + { + /** @var FactoryProvider $factoryProvider */ + $factoryProvider = $this->container->injectDependenciesMethod($this->customClass, 'setMultiple'); - $this->assertInstanceOf(FactoryProvider::class, $returnValue); + $this->assertInstanceOf(FactoryProvider::class, $factoryProvider); + $this->assertSame(self::STR, $factoryProvider->getStr()); + } + + public function testInjectDependenciesMethodWithMultipleArgumentsDefault(): void + { + /** @var FactoryProvider $factoryProvider */ + $factoryProvider = $this->container->injectDependenciesMethod( + $this->customClass, + 'setDefaults', + ['str' => self::STR] + ); + + $this->assertInstanceOf(FactoryProvider::class, $factoryProvider); + $this->assertSame(self::STR, $factoryProvider->getStr()); } public function testInjectDependencies(): void @@ -91,8 +125,10 @@ public function testInjectDependencies(): void public function testGetParameterClassName() { $reflectionParameter = new ReflectionParameter(self::REFLECTION_PARAMETERS, 'factoryProvider'); - $result = $this->getPrivateMethod('getParameterClassName', [$reflectionParameter]); - $this->assertSame(FactoryProvider::class, $result); + /** @var FactoryProvider $factoryProvider */ + $factoryProvider = $this->getPrivateMethod('getParameterClassName', [$reflectionParameter]); + + $this->assertSame(FactoryProvider::class, $factoryProvider); } } diff --git a/tests/Provider/CustomClass.php b/tests/Provider/CustomClass.php index a97224c..ffab3fb 100644 --- a/tests/Provider/CustomClass.php +++ b/tests/Provider/CustomClass.php @@ -27,4 +27,14 @@ public function setFactoryProviderSecond(FactoryProvider $factoryProvider): Fact { return $factoryProvider; } + + public function setMultiple(FactoryProvider $factoryProvider, string $str = 'test'): FactoryProvider + { + return $factoryProvider->setStr($str); + } + + public function setDefaults(FactoryProvider $factoryProvider, string $str): FactoryProvider + { + return $factoryProvider->setStr($str); + } } diff --git a/tests/Provider/FactoryProvider.php b/tests/Provider/FactoryProvider.php index c14c95f..a7f424e 100644 --- a/tests/Provider/FactoryProvider.php +++ b/tests/Provider/FactoryProvider.php @@ -6,4 +6,17 @@ class FactoryProvider { + private string $str; + + public function getStr(): string + { + return $this->str; + } + + public function setStr(string $str): FactoryProvider + { + $this->str = $str; + + return $this; + } }