malocher/zf2-event-store-module

为 Zend Framework 2 集成 EventStore

dev-master 2014-01-26 20:07 UTC

This package is not auto-updated.

Last update: 2024-09-24 01:41:06 UTC


README

这是一个集成 Malocher EventStore 到您的 ZF2 应用程序的 Zend Framework 2 模块,通过 Malocher EventStore

Build Status

安装

MalocherEventStoreModule 的安装使用 composer。有关 composer 文档,请参阅 getcomposer.org。将以下要求添加到您的 composer.json 中

"malocher/zf2-event-store-module" : "dev-master"

然后,将 MalocherEventStoreModule 添加到您的 config/application.config.php

不使用 composer 的安装不受官方支持,并且需要您安装和自动加载在 composer.json 中指定的依赖项。

设置

使用您的模块或应用程序配置设置 EventStore。将所有 EventStore 选项放在 malocher.eventstore 键下。

  'malocher.eventstore' => array(
        ...
  )

MalocherEventStoreModule 随带一个 Zf2EventStoreAdapter。您可以通过 malocher.eventstore.adapter.connection 配置设置 ZF2 数据库适配器。使用与正常 ZF2 数据库适配器相同的适配器选项。查看 ZF2 文档 以获取所有可用选项。以下是一个设置 SQLite 内存适配器的示例

'malocher.eventstore' => array(
    'adapter' => array(
        'MalocherEventStoreModule\Adapter\Zf2EventStoreAdapter' => array(
            'connection' => array(
                'driver' => 'Pdo_Sqlite',
                'database' => ':memory:'
            )
        )
    ),
)

目前,您必须自己创建数据库模式。我们正在开发一个命令行工具,以帮助您设置 EventStore。存储需要为每个 EventSourcedObject(AggregateRoot,如果您使用 DDD)一个 snapshot 表和一个 event stream 表。

以下是用于 SQLite 的示例模式

-- create one snapshot table
CREATE TABLE snapshot 
(
    id INTEGER PRIMARY KEY,
    sourceType TEXT,
    sourceId  TEXT,
    snapshotVersion INTEGER
)

-- create a table for each of your EventSourcedObjects
-- by default My\Namespaced\Object leads to the table name object_stream
CREATE TABLE <object name here>_stream 
(
    eventId TEXT PRIMARY KEY,
    sourceId TEXT,
    sourceVersion INTEGER,
    eventClass TEXT,
    payload TEXT,
    eventVersion REAL,
    timestamp INTEGER
)

使用方法

使用 ZF2 ServiceManger 获取 Malocher\EventStore 的实例。ServiceFactory 将您的 malocher.eventstore 配置传递给 EventStore,因此它已准备好保存和加载您的 EventSourcedObjects。

use Malocher\EventStore\EventStore;
use Malocher\EventStore\StoreEvent\PostPersistEvent;

/* @var $eventStore EventStore */
$eventStore = $serviceManager->get('malocher.eventstore');

//You can listen to the eventstore.events_post_persist event to be notified 
//when an object was changed
$eventstore->events()->attach(PostPersistEvent::NAME, function(PostPersistEvent $e) {
    foreach ($e->getPersistedEvents() as $persitedEvent) {
        if ($persistedEvent instanceof \My\Event\UserNameChangedEvent) {
            $oldName = $persistedEvent->getPayload()['oldName'];
            $newName = $persistedEvent->getPayload()['newName'];
            echo "Name changed from $oldName to $newName";
        }
    }
});

$userRepository = $eventStore->getRepository('My\User');

//Assuming username is the primary key 
$user = $userRepository->find('John');

$user->changeName('Malocher');

$userRepository->save($user);

//Output: Name changed from John to Malocher

ZF2 集成

在上一个示例中,我们展示了如何监听 EventStore 的 PostPersistEvent。我们使用了 $eventStore->events()->attach(...),这与原始 EventStore 实现有重要区别。默认情况下,Malocher EventStore 使用 Symfony EventDispatcher,但为了 ZF2 版本,我们将其替换为 ZF2 EventManagerProxy。您可以通过 ZF2 或 Symfony 方式添加监听器,这取决于您。好消息是,您可以通过 ZF2 SharedEventManager 通过附加监听器使用灵活的 SharedEventCollections 概念。

use Malocher\EventStore\EventStore;
use Malocher\EventStore\StoreEvent\PostPersistEvent;

//in a module bootstrap
$sharedEventManager = $serviceManager->get('SharedEventManager');

$sharedEventManager->attach(
    'EventStore',
    PostPersistEvent::NAME,
    function(PostPersistEvent $e) {
    foreach ($e->getPersistedEvents() as $persitedEvent) {
        if ($persistedEvent instanceof \My\Event\UserNameChangedEvent) {
            $oldName = $persistedEvent->getPayload()['oldName'];
            $newName = $persistedEvent->getPayload()['newName'];
            echo "Name changed from $oldName to $newName";
        }
    }
);

//somewhere else in your application ...

$userRepository = $eventStore->getRepository('My\User');

//Assuming username is the primary key 
$user = $userRepository->find('John');

$user->changeName('Malocher');

$userRepository->save($user);

//Output: Name changed from John to Malocher