diff --git a/src/Attribute/Inject.php b/src/Attribute/Inject.php index 7f2d36ff..bd7a42f7 100644 --- a/src/Attribute/Inject.php +++ b/src/Attribute/Inject.php @@ -10,7 +10,7 @@ final class Inject { public function __construct( - public readonly string|null $service = null, + public readonly string $service, ) { } } diff --git a/src/CommandBus/Handler/ParameterResolver.php b/src/CommandBus/Handler/ParameterResolver.php index 88ad6166..69238e9e 100644 --- a/src/CommandBus/Handler/ParameterResolver.php +++ b/src/CommandBus/Handler/ParameterResolver.php @@ -7,7 +7,7 @@ use Patchlevel\EventSourcing\Attribute\Inject; use Psr\Container\ContainerInterface; use ReflectionMethod; -use RuntimeException; +use ReflectionParameter; use Symfony\Component\TypeInfo\Type\ObjectType; use Symfony\Component\TypeInfo\TypeResolver\TypeResolver; @@ -22,35 +22,34 @@ public static function resolve(ReflectionMethod $method, ContainerInterface|null continue; // skip first parameter (command) } - $attributes = $parameter->getAttributes(Inject::class); - - if ($attributes === []) { - throw new RuntimeException('missing inject attribute'); + if (!$container) { + throw ServiceNotResolvable::missingContainer(); } - $serviceName = $attributes[0]->newInstance()->service; - - if ($serviceName === null) { - $reflectionType = $parameter->getType(); + yield $container->get(self::serviceName($method, $parameter)); + } + } - if ($reflectionType === null) { - throw new RuntimeException('missing type hint'); - } + private static function serviceName(ReflectionMethod $method, ReflectionParameter $parameter): string + { + $attributes = $parameter->getAttributes(Inject::class); - $type = TypeResolver::create()->resolve($reflectionType); + if ($attributes !== []) { + return $attributes[0]->newInstance()->service; + } - if (!$type instanceof ObjectType) { - throw new RuntimeException('type hint must be object'); - } + $reflectionType = $parameter->getType(); - $serviceName = $type->getClassName(); - } + if ($reflectionType === null) { + throw ServiceNotResolvable::missingType($method->getDeclaringClass()->getName(), $parameter->getName()); + } - if (!$container) { - throw new RuntimeException('missing inject attribute'); - } + $type = TypeResolver::create()->resolve($reflectionType); - yield $container->get($serviceName); + if (!$type instanceof ObjectType) { + throw ServiceNotResolvable::typeNotObject($method->getDeclaringClass()->getName(), $parameter->getName()); } + + return $type->getClassName(); } } diff --git a/src/CommandBus/Handler/ServiceNotResolvable.php b/src/CommandBus/Handler/ServiceNotResolvable.php new file mode 100644 index 00000000..44a38281 --- /dev/null +++ b/src/CommandBus/Handler/ServiceNotResolvable.php @@ -0,0 +1,23 @@ + new SystemClock(), + 'env' => 'test', ]), ); diff --git a/tests/Integration/BasicImplementation/ProfileWithCommands.php b/tests/Integration/BasicImplementation/ProfileWithCommands.php index f542c510..da56535d 100644 --- a/tests/Integration/BasicImplementation/ProfileWithCommands.php +++ b/tests/Integration/BasicImplementation/ProfileWithCommands.php @@ -28,8 +28,8 @@ final class ProfileWithCommands extends BasicAggregateRoot #[Handle] public static function create( CreateProfile $command, - #[Inject] ClockInterface $clock, + #[Inject('env')] string $env, ): self { $self = new self(); $self->recordThat(new ProfileCreated($command->id, $command->name)); @@ -40,8 +40,8 @@ public static function create( #[Handle] public function changeName( ChangeProfileName $command, - #[Inject] ClockInterface $clock, + #[Inject('env')] string $env, ): void { $this->recordThat(new NameChanged($command->name)); }