Prooph中InMemoryEventStore和PdoEventStore不兼容如何解决?
How to solve incompatibility of InMemoryEventStore and PdoEventStore in 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
);
最后我只是检查记录的事件并断言这是我所期望的。但是我在 MysqlEventStore
和 InMemoryEventStore
之间切换时遇到问题,因为 MysqlEventStore
不是事务性的(因此在 saveAggregateRoot
方法中发出事件),而不是 InMemoryEventStore
这是事务性的(因此在提交方法中发出事件)。
我的仓库保存方法很简单:
class ProophFooRepository extends AggregateRepository implements FooRepository
{
public function save(FooAggregate $foo): void
{
$this->saveAggregateRoot($foo);
}
...
}
如何制作它以便我可以更改我想使用的任何事件存储(内存或 pdo)并且它会起作用?我是否应该在我的存储库中设置条件 if($this->isTransactionalEventStore())
(然后开始事务并提交)?我不喜欢那样。 :(
为什么只有 InMemoryEventStore 是事务性的?同时拥有 InMemoryTransactionalEventStore
和 InMemoryEventStore
不是更好吗?因为我想用 InMemoryEventStore 进行测试 运行,而通常我使用 PdoEventStore。
编辑:当我将 InMemoryEventStoreFactory 中的第 100 行更改为
$wrapper = new ActionEventEmitterEventStore($eventStore, $eventEmitter);
并使 InMemoryEventStore
实现 EventStore
而不是 TransactionalEventStore
,一切正常。所以要么我在某种程度上没有正确使用 prooph 并且不需要它,要么可以通过 PR 将 ImMemoryEventStore
拆分为 InMemoryTransactionalEventStore
和 InMemoryEventStore
?
轻松修复
这是一个非常有效的问题。问题是,在处理 v7 事件存储实现时,我没有考虑过这个用例。如您所述,解决方法是使用 ActionEventEmitterEventStore 包装。然而,内存事件存储中的非事务性将是更好的选择(当时不存在)。
目前 InMemoryEventStore 是事务性的,因此删除该功能并将其放入 TransactionalInMemoryEventStore 将是一个 BC 中断,如果没有新的主要版本,我们将无法做到这一点。这就是为什么我认为,我们应该创建一个名为 NonTransactionalInMemoryEventStore 的新实现。我在这里创建了一张票:https://github.com/prooph/event-store/issues/307。想接手并提供 PR 吗?
我正在像这样测试我的命令处理程序:
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
);
最后我只是检查记录的事件并断言这是我所期望的。但是我在 MysqlEventStore
和 InMemoryEventStore
之间切换时遇到问题,因为 MysqlEventStore
不是事务性的(因此在 saveAggregateRoot
方法中发出事件),而不是 InMemoryEventStore
这是事务性的(因此在提交方法中发出事件)。
我的仓库保存方法很简单:
class ProophFooRepository extends AggregateRepository implements FooRepository
{
public function save(FooAggregate $foo): void
{
$this->saveAggregateRoot($foo);
}
...
}
如何制作它以便我可以更改我想使用的任何事件存储(内存或 pdo)并且它会起作用?我是否应该在我的存储库中设置条件 if($this->isTransactionalEventStore())
(然后开始事务并提交)?我不喜欢那样。 :(
为什么只有 InMemoryEventStore 是事务性的?同时拥有 InMemoryTransactionalEventStore
和 InMemoryEventStore
不是更好吗?因为我想用 InMemoryEventStore 进行测试 运行,而通常我使用 PdoEventStore。
编辑:当我将 InMemoryEventStoreFactory 中的第 100 行更改为
$wrapper = new ActionEventEmitterEventStore($eventStore, $eventEmitter);
并使 InMemoryEventStore
实现 EventStore
而不是 TransactionalEventStore
,一切正常。所以要么我在某种程度上没有正确使用 prooph 并且不需要它,要么可以通过 PR 将 ImMemoryEventStore
拆分为 InMemoryTransactionalEventStore
和 InMemoryEventStore
?
这是一个非常有效的问题。问题是,在处理 v7 事件存储实现时,我没有考虑过这个用例。如您所述,解决方法是使用 ActionEventEmitterEventStore 包装。然而,内存事件存储中的非事务性将是更好的选择(当时不存在)。
目前 InMemoryEventStore 是事务性的,因此删除该功能并将其放入 TransactionalInMemoryEventStore 将是一个 BC 中断,如果没有新的主要版本,我们将无法做到这一点。这就是为什么我认为,我们应该创建一个名为 NonTransactionalInMemoryEventStore 的新实现。我在这里创建了一张票:https://github.com/prooph/event-store/issues/307。想接手并提供 PR 吗?