如何在Prooph中解决InMemoryEventStore和PdoEventStore的不兼容问题?

时间:2017-10-16 11:33:30

标签: php event-sourcing prooph

我正在以某种方式测试我的命令处理程序:

public function testHandle_ShouldPublishFooEvent(): void
{
    $fooCommand = $this->givenFooCommand();

    $this->whenHandleCommand($fooCommand);

    $this->thenFooEventIsPublished();
}

基本上,当命令处理程序中没有验证逻辑时,我只测试快乐的场景。我通过检查预期事件是否发布到事件总线来测试它。在whenHandleCommand方法中将测试的命令发送到命令总线之前,我开始记录调度事件,如:

$eventBus->attach(
    EventBus::EVENT_DISPATCH,
    function (ActionEvent $actionEvent) use ($events): void {
        $event = $actionEvent->getParam(MessageBus::EVENT_PARAM_MESSAGE);
        $events->addEvent($event);
    },
    -1000
);

最后我只是检查记录的事件并断言它是我所期望的。但我在MysqlEventStoreInMemoryEventStore之间切换时遇到问题,因为MysqlEventStore不是事务性的(因此在saveAggregateRoot方法中发出事件),而不是InMemoryEventStore这是事务性的(因此在commit方法中发出事件)。

我的存储库保存方法非常简单:

class ProophFooRepository extends AggregateRepository implements FooRepository
{
    public function save(FooAggregate $foo): void
    {
        $this->saveAggregateRoot($foo);
    }
    ...
}

如何制作它以便我可以更改我想要使用的任何事件存储(内存或pdo)并且它将起作用?我应该在我的存储库中有条件if($this->isTransactionalEventStore())(然后开始事务和提交)吗?我不喜欢那样。 :(

为什么只有InMemoryEventStore是事务性的?同时拥有InMemoryTransactionalEventStoreInMemoryEventStore不应该更好吗?因为我希望我的测试使用InMemoryEventStore运行,而通常我使用PdoEventStore。

编辑:当我将InMemoryEventStoreFactory中的第100行更改为

$wrapper = new ActionEventEmitterEventStore($eventStore, $eventEmitter);

并使InMemoryEventStore实现EventStore而不是TransactionalEventStore,一切正常。所以要么我在某种程度上没有正确使用prooph并且不需要它,或者它可以通过公关将ImMemoryEventStore拆分为InMemoryTransactionalEventStoreInMemoryEventStore来轻松修复?

1 个答案:

答案 0 :(得分:1)

这是一个非常有效的问题。问题是,在处理v7事件存储实现时,我没有考虑这个用例。解决方法是使用ActionEventEmitterEventStore进行换行,如您所述。然而,非事务性的内存事件存储将是更好的选择(当时不存在)。

目前InMemoryEventStore是事务性的,因此删除该功能并将其放入TransactionalInMemoryEventStore将是BC中断,我们离不开新的主要版本。这就是为什么我认为,我们应该创建一个名为NonTransactionalInMemoryEventStore的新实现。我在这里创建了一张票:https://github.com/prooph/event-store/issues/307。想接管它并提供PR?