EventSourcedRootEntityのメモ


<?php
trait EventSourcedRootEntity
{
    /**
     * @var DomainEvent[]
     */
    private $mutatingEvents = [];

    public function apply(DomainEvent $event)
    {
        $this->mutatingEvents[] = $event;
        $this->mutateWhen($event);
    }

    private function mutateWhen(DomainEvent $domainEvent)
    {
        $eventType = (new \ReflectionClass($domainEvent))->getShortName();
        $mutatorMethodName = 'when'.$eventType;

        if (method_exists($this, $mutatorMethodName) === false) {
            throw new \RuntimeException(
                sprintf("Method %s() does not exist", $mutatorMethodName)
            );
        }

        try {
            $mutatorMethod = new \ReflectionMethod($this, $mutatorMethodName);
            $mutatorMethod->setAccessible(true);
            $mutatorMethod->invoke($this, $domainEvent);
        } catch (\ReflectionException $e) {
            throw new \RuntimeException(
                sprintf("Method %s() failed", $mutatorMethodName), null, $e
            );
        }
    }
}