Friday, February 26, 2016

Inheritance with Aggregate Roots in ProophEvent-Store

If you want to make inheritance work with aggregate roots using a common repository for all subtypes, this can be achieved very easily. You need the latest ProophEvent-Store v6.1 to do this.

An example


Consider the following use case:

<?php
abstract class User extends \Prooph\EventSourcing\AggregateRoot
{
    protected $name;

    protected $email;

    public function name()
    {
        return $this->name;
    }

    public function email()
    {
        return $this->email;
    }

    protected function whenUserWasRegisterd(UserWasRegisterd $event)
    {
        $this->name = $event->name();
        $this->email = $event->email();
    }
}

class Admin extends User
{
    public static function register($name, $email)
    {
        $self = new self();
        $self->recordThat(UserWasRegisterd::withData('admin', $name, $email);

        return $self;
    }
}

class Member extends User
{
    public static function register($name, $email)
    {
        $self = new self();
        $self->recordThat(UserWasRegisterd::withData('member', $name, $email);

        return $self;
    }
}
So in order to make this work, you need 3 small changes in your application.

Step 1: Create a UserAggregateTranslator


<?php
final class UserAggregateTranslator extends \Prooph\EventSourcing\EventStoreIntegration\AggregateTranslator
{
    /**
     * @param \Prooph\EventStore\Aggregate\AggregateType $aggregateType
     * @param \Iterator $historyEvents
     * @return object reconstructed AggregateRoot
     */
    public function reconstituteAggregateFromHistory(
        \Prooph\EventStore\Aggregate\AggregateType $aggregateType, 
        \Iterator $historyEvents
    ) {
        $aggregateRootDecorator = $this->getAggregateRootDecorator();

        $firstEvent = $historyEvents->current();
        $type = $firstEvent->type();

        if ($type === 'admin') {
            return $aggregateRootDecorator->fromHistory(Admin::class, $historyEvents);
        } elseif ($type === 'member') {
            return $aggregateRootDecorator->fromHistory(Member::class, $historyEvents);
        }
    }
}

Step 2: Change the assertion method in the EventStoreUserCollection


<?php
final class EventStoreUserCollection extends 
    \Prooph\EventStore\Aggregate\AggregateRepository
{
    public function add(User $user)
    {
        $this->addAggregateRoot($user);
    }
    public function get(UserId $userId)
    {
        return $this->getAggregateRoot($userId->toString());
    }
    protected function assertAggregateType($eventSourcedAggregateRoot)
    {
        \Assert\Assertion::isInstanceOf($eventSourcedAggregateRoot, User::class);
    }
}

Step 3: Make use of your custom AggregateTranslator


<?php
final class EventStoreUserCollectionFactory
{
    public function __invoke(ContainerInterface $container)
    {
        return new EventStoreUserCollection(
            $container->get(EventStore::class),
            AggregateType::fromAggregateRootClass(User::class),
            new UserAggregateTranslator()
        );
    }
}

If you use the provided container factory (\Prooph\EventStore\Container\Aggregate\AbstractAggregateRepositoryFactory) then you can also just change the aggregate_translator key in your config to point to the new UserAggregateTranslator and register the UserAggregateTranslator in your container.

9 comments:

  1. Excellent article on "Inheritance with Aggregate Roots in ProophEvent-Store." The instruction on the aggregate translators is to the point. The listed codings are easy to follow and implement. Thanks for the article. Keep sharing more. Digital marketing courses in Nagpur

    ReplyDelete
  2. The article "Inheritance with Aggregate Roots in ProophEvent-Store" is amazing. The guidance for aggregate translators is clear and concise. The coding that are presented are simple to use and implement. I appreciate the article. Thank you! Keep up the good work.
    Data Analytics Courses in Ghana

    ReplyDelete
  3. The article "Inheritance with Aggregate Roots in ProophEvent-Store" is excellent. Very useful and well-written blog.
    I'll pass this along to my friends and promote it. Continue your good work!
    Digital Marketing Courses in Australia

    ReplyDelete
  4. It's a great essay called "Inheritance with Aggregate Roots in ProophEvent-Store." Well-written and quite helpful blog.
    This blog has taught me a lot. Please share more of your greatest blogs with us. Continue updating and posting!
    Digital Marketing Courses in Vancouver

    ReplyDelete
  5. It's a great article on "Inheritance with Aggregate Roots in ProophEvent-Store." The aggregate translators are well-written, which makes the readers to follow and implement. I appreciate your thorough description of the coding. I appreciate the time and effort you put into the blog. Continue sharing.
    Courses after bcom

    ReplyDelete
  6. The technicalities of this article on sharing knowledge on making inheritance work with aggregate roots by using a common repository with given examples is too helpful and well explained. Keep sharing and continuing blogging.
    Data Analytics Courses in New Zealand

    ReplyDelete
  7. The post on "Inheritance with Aggregate Roots in ProophEvent-Store" was really informative. This is one of the better sources I've seen in a while. Excellent information that is well written. I'm really appreciative that you shared this with us and made it available for us to read. Continue speaking.
    Data Analytics Courses in Mumbai

    ReplyDelete
  8. Nice blog! This article's technical explanations on how to use a common repository and aggregate roots to make inheritance work are quite helpful and well-explained. Continue blogging and sharing. Thanks again.
    Data Analytics Courses in Gurgaon

    ReplyDelete
  9. I loved the way you shared so much information in a short and crisp post. Keep sharing and spreading knowledge through your blogs.
    Digital Marketing Courses in Adelaide

    ReplyDelete