Skip to content

Commit

Permalink
refactor parameter resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBadura committed Dec 21, 2024
1 parent 2dc7a30 commit b8e8a42
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 58 deletions.
8 changes: 2 additions & 6 deletions src/CommandBus/Handler/CreateAggregateHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
) {
}

Expand All @@ -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)],

Check failure on line 32 in src/CommandBus/Handler/CreateAggregateHandler.php

View workflow job for this annotation

GitHub Actions / Static Analysis by Psalm (locked, 8.3, ubuntu-latest)

InvalidOperand

src/CommandBus/Handler/CreateAggregateHandler.php:32:17: InvalidOperand: Cannot use spread operator on iterable with key type mixed (see https://psalm.dev/058)
);

if (!$aggregate instanceof AggregateRoot) {
Expand Down
4 changes: 2 additions & 2 deletions src/CommandBus/Handler/DefaultHandlerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function createHandler(string $aggregateClass, string $method): callable
$this->repositoryManager,
$aggregateClass,
$method,
$this->container,
new DefaultParameterResolver($this->container),
);
}

Expand All @@ -31,7 +31,7 @@ public function updateHandler(string $aggregateClass, string $method): callable
$this->repositoryManager,
$aggregateClass,
$method,
$this->container,
new DefaultParameterResolver($this->container),
);
}
}
61 changes: 61 additions & 0 deletions src/CommandBus/Handler/DefaultParameterResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

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;

final class DefaultParameterResolver implements ParameterResolver
{
public function __construct(
private readonly ContainerInterface|null $container = null,
) {
}

/** @return iterable<mixed> */
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();
}
}
46 changes: 2 additions & 44 deletions src/CommandBus/Handler/ParameterResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<mixed> */
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;
}
8 changes: 2 additions & 6 deletions src/CommandBus/Handler/UpdateAggregateHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
) {
}

Expand All @@ -35,10 +34,7 @@ public function __invoke(object $command): void

$reflectionMethod->invokeArgs(
$aggregate,
[
$command,
...ParameterResolver::resolve($reflectionMethod, $this->container),
],
[...$this->parameterResolver->resolve($reflectionMethod, $command)],

Check failure on line 37 in src/CommandBus/Handler/UpdateAggregateHandler.php

View workflow job for this annotation

GitHub Actions / Static Analysis by Psalm (locked, 8.3, ubuntu-latest)

InvalidOperand

src/CommandBus/Handler/UpdateAggregateHandler.php:37:17: InvalidOperand: Cannot use spread operator on iterable with key type mixed (see https://psalm.dev/058)
);

$repository->save($aggregate);
Expand Down

0 comments on commit b8e8a42

Please sign in to comment.