Broadway just got a new release


Today we tagged version 0.3.0 for Broadway. In this version we have merged some nice pull requests from various contributors, thanks to everybody that submitted issues and/or pull requests!

One of the pull requests we received is from simensen. He added factories for our aggregates.

AggregateFactory

Before this pull request, there was only one sane way to instantiate aggregates. You would be required to have a public constructor without arguments. Although this might work for a lot of cases, a lot of people want there aggregate root to have a private constructor and use a named constructor, for example: Invitation::createWithEmail($email).

The public constructor wasn't meant to be a requirement, but was a bad design decision in our EventSourcingRepository. When we loaded the events to instantiate the aggregate we just created the aggregate with new $this->aggregateClass, and there wasn't an easy way to override this, except to override the whole method.

But now the aggregate factory is introduced. A aggregate factory has the responsibility to create an aggregate for the given aggregateClass and DomainEventStream.

/**
 * @param string                     $aggregateClass    the FQCN of the Aggregate to create
 * @param DomainEventStreamInterface $domainEventStream
 *
 * @return \Broadway\EventSourcing\EventSourcedAggregateRoot
 */
public function create($aggregateClass, DomainEventStreamInterface $domainEventStream);

At this moment there are 2 factories: PublicConstructorAggregateFactory and NamedConstructorAggregateFactory.

PublicConstructorAggregateFactory is the original. This factory creates the aggregate by calling the constructor without arguments and calling initializeState with given domainEventStream directly after.

class Account extends Broadway\EventSourcing\EventSourcedAggregateRoot
{
}

$repository = new Broadway\EventSourcing\EventSourcingRepository(
    $eventStore,
    $eventBus,
    'Account',
    new Broadaway\EventSourcing\AggregateFactory\PublicConstructorAggregateFactory()
);
$repository->load(42); // will call: new Account();

NamedConstructorAggregateFactory is the factory that triggered the pull request. With this factory you can instantiate an aggregate using a named constructor.

class Account extends Broadway\EventSourcing\EventSourcedAggregateRoot
{
    private function __construct()
    {
    }

    public static function instantiateForReconstitution()
    {
        return new self;
    }
}

$repository = new Broadway\EventSourcing\EventSourcingRepository(
    $eventStore,
    $eventBus,
    'Account',
    new Broadaway\EventSourcing\AggregateFactory\NamedConstructorAggregateFactory('instantiateForReconstitution')
);
$repository->load(42); // will call: Account::instantiateForReconstitution();

More contributors

But of course we had many more contributors that sent pull requests, thank you all!