From 0aa514eb695847bbe5b784c27e6bf24016a22308 Mon Sep 17 00:00:00 2001 From: James Walker <jh_walker@outlook.com> Date: Sun, 12 Nov 2023 13:48:04 +0000 Subject: [PATCH] Container::resolve() support falling back to default value after failing to resolve parameters for class used as parameter in class we're constructing --- src/DI/Container.php | 21 +++++++++--------- tests/DI/ContainerTests.php | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/DI/Container.php b/src/DI/Container.php index be1b2a8..c204f92 100644 --- a/src/DI/Container.php +++ b/src/DI/Container.php @@ -75,23 +75,24 @@ class Container { * @param array $args optional Constructor named arguments available * @return array */ - public function resolve( - $class, $method, array $args=[]) : array { + public function resolve($class, $method, array $args=[]) : array { $resolved = []; $arguments = Resolver::get_method_args($class, $method); - //Iterate args foreach ($arguments as $arg) { - //Reset value + $value = null; - //If has a type string, try to get - // a class instance from the container + /** Type string = get a class instance from the container */ if ($arg -> typeStr) { - // May fail if not valid class, catch acceptable - // exceptions and allow continuing resolve from Resolver + /** + * May fail if not a valid class + * + * We catch acceptable exceptions and allow the + * resolution attempt to continue via the Resolver. + */ try { $value = $this -> instance( $arg -> typeStr, @@ -99,8 +100,7 @@ class Container { (is_string($class) ? $class : get_class($class)) ); } - catch (Exceptions\InvalidClassException $ex) { - } + catch (Exceptions\InvalidClassException|Exceptions\ReflectionArgumentResolve $ex) {} } @@ -109,6 +109,7 @@ class Container { } $resolved[] = $value; + } return $resolved; diff --git a/tests/DI/ContainerTests.php b/tests/DI/ContainerTests.php index ffef221..35b3206 100644 --- a/tests/DI/ContainerTests.php +++ b/tests/DI/ContainerTests.php @@ -63,6 +63,38 @@ class TestClass { } + + /** + * Argument resolution test when a class used as a parameter, with a + * default value, has its own required parameters. + * + * @param ?\ArdeidaeTests\DI\TestClassWithParam $Test optional (`null`) + * @return void + */ + public function resolveOptionalClassParameterHasRequiredParameters(?TestClassWithParam $Test=null) : void { + + //... + + } + +} + +/** + * Test class that takes a constructor parameter + * + * @package Ardeidae + * @subpackage Tests + * @author James Walker + * @license MIT License + */ +class TestClassWithParam { + + /** + * Constructor. + */ + public function __construct( + public string $foo) {} + } /** @@ -443,6 +475,17 @@ class ContainerTests extends Trainline\Framework\Unit { } + /** + * Argument resolution - parameter class has a required parameter + * but a default value is available (we should use the default value + * if the class can't be constructed due to a missing parameter). + */ + public function resolveWhenOptionalClassParameterHasRequiredParameters() : void { + $result = $this -> getDic() -> resolve(self::TEST_CLASS, "resolveOptionalClassParameterHasRequiredParameters"); + assertions\assrt(($result && is_null($result[0]))); + } + + /** * Argument resolution - including with DI instances. * -- GitLab