diff --git a/src/CommandBus/SymfonyParameterResolver.php b/src/CommandBus/SymfonyParameterResolver.php index 2fa9c41f..12d79643 100644 --- a/src/CommandBus/SymfonyParameterResolver.php +++ b/src/CommandBus/SymfonyParameterResolver.php @@ -5,9 +5,14 @@ namespace Patchlevel\EventSourcingBundle\CommandBus; use Patchlevel\EventSourcing\CommandBus\Handler\ParameterResolver; +use Patchlevel\EventSourcing\CommandBus\Handler\ServiceNotResolvable; use Psr\Container\ContainerInterface; use ReflectionMethod; +use Symfony\Component\TypeInfo\Type\ObjectType; +use Symfony\Component\TypeInfo\TypeResolver\TypeResolver; +use function is_a; +use function sprintf; use function strtolower; final class SymfonyParameterResolver implements ParameterResolver @@ -22,14 +27,39 @@ public function resolve(ReflectionMethod $method, object $command): iterable { $prefix = strtolower($method->getName()) . '.'; - foreach ($method->getParameters() as $index => $parameter) { - if ($index === 0) { - yield $command; // first parameter is always the command + foreach ($method->getParameters() as $parameter) { + $serviceId = $prefix . $parameter->getName(); + + $this->container->has($serviceId); + + if ($this->container->has($serviceId)) { + yield $this->container->get($serviceId); + + continue; + } + + $reflectionType = $parameter->getType(); + + if ($reflectionType === null) { + ServiceNotResolvable::missingType($method->getDeclaringClass()->getName(), $parameter->getName()); + } + + $type = TypeResolver::create()->resolve($reflectionType); + + if ($type instanceof ObjectType && is_a($command, $type->getClassName(), true)) { + yield $command; continue; } - yield $this->container->get($prefix . $parameter->getName()); + throw new ServiceNotResolvable( + sprintf( + 'Missing service for parameter "%s" in "%s::%s"', + $parameter->getName(), + $method->getDeclaringClass()->getName(), + $method->getName(), + ), + ); } } } diff --git a/src/DependencyInjection/HandlerServiceLocatorCompilerPass.php b/src/DependencyInjection/HandlerServiceLocatorCompilerPass.php index 87eb52a6..6de89f44 100644 --- a/src/DependencyInjection/HandlerServiceLocatorCompilerPass.php +++ b/src/DependencyInjection/HandlerServiceLocatorCompilerPass.php @@ -56,11 +56,7 @@ private function services(ReflectionMethod $method, ContainerInterface $containe $services = []; $prefix = strtolower($method->getName()) . '.'; - foreach ($method->getParameters() as $index => $parameter) { - if ($index === 0) { - continue; // skip first parameter (command) - } - + foreach ($method->getParameters() as $parameter) { $key = $prefix . $parameter->getName(); $attributes = $parameter->getAttributes(Inject::class); @@ -102,6 +98,10 @@ private function services(ReflectionMethod $method, ContainerInterface $containe continue; } + if (!$container->has($type->getClassName())) { + continue; + } + $services[$key] = new Reference($type->getClassName()); }