diff --git a/src/CommandBus/Handler/CreateAggregateHandler.php b/src/CommandBus/Handler/CreateAggregateHandler.php index ae319abdb..82e6e839b 100644 --- a/src/CommandBus/Handler/CreateAggregateHandler.php +++ b/src/CommandBus/Handler/CreateAggregateHandler.php @@ -7,7 +7,6 @@ use InvalidArgumentException; use Patchlevel\EventSourcing\Aggregate\AggregateRoot; use Patchlevel\EventSourcing\Repository\RepositoryManager; -use Psr\Container\ContainerInterface; use ReflectionClass; final class CreateAggregateHandler @@ -17,7 +16,7 @@ public function __construct( private readonly RepositoryManager $repositoryManager, private readonly string $aggregateClass, private readonly string $methodName, - private readonly ContainerInterface|null $container = null, + private readonly ParameterResolver $parameterResolver, ) { } @@ -30,10 +29,7 @@ public function __invoke(object $command): void $aggregate = $reflectionMethod->invokeArgs( null, - [ - $command, - ...ParameterResolver::resolve($reflectionMethod, $this->container), - ], + [...$this->parameterResolver->resolve($reflectionMethod, $command)], ); if (!$aggregate instanceof AggregateRoot) { diff --git a/src/CommandBus/Handler/DefaultHandlerFactory.php b/src/CommandBus/Handler/DefaultHandlerFactory.php index 853047632..b371c8325 100644 --- a/src/CommandBus/Handler/DefaultHandlerFactory.php +++ b/src/CommandBus/Handler/DefaultHandlerFactory.php @@ -21,7 +21,7 @@ public function createHandler(string $aggregateClass, string $method): callable $this->repositoryManager, $aggregateClass, $method, - $this->container, + new DefaultParameterResolver($this->container), ); } @@ -31,7 +31,7 @@ public function updateHandler(string $aggregateClass, string $method): callable $this->repositoryManager, $aggregateClass, $method, - $this->container, + new DefaultParameterResolver($this->container), ); } } diff --git a/src/CommandBus/Handler/DefaultParameterResolver.php b/src/CommandBus/Handler/DefaultParameterResolver.php new file mode 100644 index 000000000..da11882d2 --- /dev/null +++ b/src/CommandBus/Handler/DefaultParameterResolver.php @@ -0,0 +1,61 @@ + */ + public function resolve(ReflectionMethod $method, object $command): iterable + { + foreach ($method->getParameters() as $index => $parameter) { + if ($index === 0) { + yield $command; // first parameter is always the command + + continue; + } + + if (!$this->container) { + throw ServiceNotResolvable::missingContainer(); + } + + yield $this->container->get(self::serviceName($method, $parameter)); + } + } + + private function serviceName(ReflectionMethod $method, ReflectionParameter $parameter): string + { + $attributes = $parameter->getAttributes(Inject::class); + + if ($attributes !== []) { + return $attributes[0]->newInstance()->service; + } + + $reflectionType = $parameter->getType(); + + if ($reflectionType === null) { + throw ServiceNotResolvable::missingType($method->getDeclaringClass()->getName(), $parameter->getName()); + } + + $type = TypeResolver::create()->resolve($reflectionType); + + if (!$type instanceof ObjectType) { + throw ServiceNotResolvable::typeNotObject($method->getDeclaringClass()->getName(), $parameter->getName()); + } + + return $type->getClassName(); + } +} diff --git a/src/CommandBus/Handler/ParameterResolver.php b/src/CommandBus/Handler/ParameterResolver.php index 69238e9ed..53145a801 100644 --- a/src/CommandBus/Handler/ParameterResolver.php +++ b/src/CommandBus/Handler/ParameterResolver.php @@ -4,52 +4,10 @@ namespace Patchlevel\EventSourcing\CommandBus\Handler; -use Patchlevel\EventSourcing\Attribute\Inject; -use Psr\Container\ContainerInterface; use ReflectionMethod; -use ReflectionParameter; -use Symfony\Component\TypeInfo\Type\ObjectType; -use Symfony\Component\TypeInfo\TypeResolver\TypeResolver; -/** @internal */ -final class ParameterResolver +interface ParameterResolver { /** @return iterable */ - public static function resolve(ReflectionMethod $method, ContainerInterface|null $container = null): iterable - { - foreach ($method->getParameters() as $index => $parameter) { - if ($index === 0) { - continue; // skip first parameter (command) - } - - if (!$container) { - throw ServiceNotResolvable::missingContainer(); - } - - yield $container->get(self::serviceName($method, $parameter)); - } - } - - private static function serviceName(ReflectionMethod $method, ReflectionParameter $parameter): string - { - $attributes = $parameter->getAttributes(Inject::class); - - if ($attributes !== []) { - return $attributes[0]->newInstance()->service; - } - - $reflectionType = $parameter->getType(); - - if ($reflectionType === null) { - throw ServiceNotResolvable::missingType($method->getDeclaringClass()->getName(), $parameter->getName()); - } - - $type = TypeResolver::create()->resolve($reflectionType); - - if (!$type instanceof ObjectType) { - throw ServiceNotResolvable::typeNotObject($method->getDeclaringClass()->getName(), $parameter->getName()); - } - - return $type->getClassName(); - } + public function resolve(ReflectionMethod $method, object $command): iterable; } diff --git a/src/CommandBus/Handler/UpdateAggregateHandler.php b/src/CommandBus/Handler/UpdateAggregateHandler.php index bb640f779..b3adfb8c5 100644 --- a/src/CommandBus/Handler/UpdateAggregateHandler.php +++ b/src/CommandBus/Handler/UpdateAggregateHandler.php @@ -9,7 +9,6 @@ use Patchlevel\EventSourcing\Aggregate\AggregateRootId; use Patchlevel\EventSourcing\Attribute\Id; use Patchlevel\EventSourcing\Repository\RepositoryManager; -use Psr\Container\ContainerInterface; use ReflectionClass; final class UpdateAggregateHandler @@ -19,7 +18,7 @@ public function __construct( private readonly RepositoryManager $repositoryManager, private readonly string $aggregateClass, private readonly string $methodName, - private readonly ContainerInterface|null $container = null, + private readonly ParameterResolver $parameterResolver, ) { } @@ -35,10 +34,7 @@ public function __invoke(object $command): void $reflectionMethod->invokeArgs( $aggregate, - [ - $command, - ...ParameterResolver::resolve($reflectionMethod, $this->container), - ], + [...$this->parameterResolver->resolve($reflectionMethod, $command)], ); $repository->save($aggregate);