jphooiveld/eventsauce-bundle

EventSauce Bundle

安装次数: 32,675

依赖项: 0

建议者: 0

安全: 0

星星: 15

观察者: 3

分支: 9

开放问题: 0

类型:symfony-bundle

v3.0.0 2023-10-25 14:36 UTC

This package is auto-updated.

Last update: 2024-08-31 00:32:14 UTC


README

BUild status Scrutinizer Code Quality Code Coverage

信息

此包集成了EventSauce,并将它的doctrine消息存储库集成到你的symfony应用中。

强烈建议在安装此包之前了解EventSauce的工作原理或阅读官方网站(https://eventsauce.io)。

安装

将包安装到你的symfony项目中。

$ composer require jphooiveld/eventsauce-bundle

安装此包会报错,因为doctrine消息存储库缺失。你必须从EventSauce项目安装doctrine消息存储库。由于EventSauce项目同时有Doctrine DBAL版本2.x和3.x的版本,所以不能同时使用,因此你需要自己选择正确的版本。该包将自动检查已安装的消息存储库的版本并加载相应的服务。

如果你使用的是Doctrine DBAL版本3.x的项目,你必须安装该包。

$ composer require eventsauce/message-repository-for-doctrine

或者,如果你使用的是Doctrine DBAL版本2.x的项目,你必须安装该包。

$ composer require eventsauce/message-repository-for-doctrine-v2

如果你想使用symfony messenger作为分发者而不是默认的分发者,你必须安装该包。

$ composer require symfony/messenger

如果你想使用控制台命令为你生成数据库表,你必须安装该包。

$ composer require symfony/console

通常symfony应该能够自动注册该包。如果不能,你需要在配置目录中的bundles.php中添加它。

<?php

return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
    Jphooiveld\Bundle\EventSauceBundle\JphooiveldEventSauceBundle::class => ['all' => true],
];

配置

jphooiveld_event_sauce:
    time_of_recording:
        # The timezone to use for recorded messages, defaults to PHP ini setting.
        timezone: UTC
    messenger:
        # Use symfony messenger instead of EventSauce's default dispatcher (needs package symfony/messenger installed).
        enabled: false
        # The name of the messenger command bus service to use.
        service_bus: messenger.bus.events
    message_repository:
        # Override if you don't want to use the default doctrine message repository but your own implementation. 
        # If doctrine is enabled this will be ignored.
        service: jphooiveld_eventsauce.message_repository.doctrine
        doctrine:
            # Use doctrine as default message repository. If you turn this off you must provide your own service.
            enabled: true
            # Service that implements a doctrine connection. We assume doctrine bundle default here.
            connection: doctrine.dbal.default_connection
            # The table name in the database to store the messages.
            table: event
            # JSON encode options for the doctrine message repository
            json_encode_options:
                - !php/const JSON_PRETTY_PRINT
                - !php/const JSON_PRESERVE_ZERO_FRACTION
            # Table schema to use: default (EventSauce 1.x) or legacy (EventSauce 0.8.x)  
            table_schema: default
            # UUID encpder to use: string or binary   
            uuid_encoder: string
        # Configure provided aggregate roots to use the default repository implementations as created by the bundle 
        aggregates:
            - App\Domain\Order
    snapshot_repository:
        # User snapshotting
        enabled: false
        # Service must point to a valid class that implements EventSauce\EventSourcing\Snapshotting\SnapshotRepository
        service: 'App\Infrastructure\MySnapshotRepository'
            

配置详情

Messenger

默认情况下,使用EventSauce的同步消息分发器。如果你启用了symfony messenger并提供了事件总线服务ID,所有消息将由messenger组件处理。

消息存储库

doctrine消息组件将自动作为依赖项安装,否则应用程序将无法正常工作。但如果你想安装另一种类型的存储库或创建自己的存储库,它很容易在服务参数中引用。如果启用了doctrine(默认启用),则将忽略此设置。

配置聚合体是绑定你的聚合体到默认EventSauce服务的消息存储库的一种简单方法。编译器传递将自动创建服务。

例如,假设你有一个名为Order的聚合根

<?php

namespace App\Domain;

use EventSauce\EventSourcing\AggregateRoot;

class Order implements AggregateRoot
{    
    // code
}

如果你将'App\Domain\Order'添加到配置中的聚合列表中,编译器传递将自动创建一个名为 jphooiveld_eventsauce.aggregate_repository.order 的服务。它还将为该存储库创建一个名为 $orderRepository 的接口绑定,接口为 EventSauce\EventSourcing\AggregateRootRepository,以便你可以将其注入到自己的服务中

假设我们有一个负责持久化订单聚合体的命令处理器。我们现在可以自动注入订单存储库以供进一步使用。

<?php

namespace App\CommandHandler;

use EventSauce\EventSourcing\AggregateRootRepository;

class AddOrderHandler
{
    public function __construct(
        private AggregateRootRepository $orderRepository,
    ) {
    }
    
    // other code
}

如果你不想配置你的存储库,则不要将其添加到列表中,然后自己配置它。

当启用快照功能,且快照服务指向有效的 EventSauce\EventSourcing\Snapshotting\SnapshotRepository 实例时,每个提供的聚合体(在消息存储库配置中的聚合体下)实现 EventSauce\EventSourcing\Snapshotting\AggregateRootWithSnapshotting 将自动配置消息存储库以及快照存储库。

自动配置

EventSauce有几个接口,在安装此包时自动配置,使你的生活更加轻松。

消费者

消费者负责处理聚合事件。消息调度器负责将事件委派给消费者。您创建的每个实现 EventSauce\EventSourcing\MessageConsumer 的类都将自动接收到消息调度器的事件。然而,如果您打算使用 Symfony 消息传递器,您必须实现 __invoke 方法。为了克服这种限制,您可以使用在包中提供的 ConsumableTrait。这将确保它与 EventSauce 的默认消息调度器以及 symfony 消息传递器组件一起工作。该特性还将让消费者以与聚合存储库相同的方式处理事件。它将查找以 apply 开头且后面跟有事件名称的方法。例如,我们有一个 OrderCreated 类,它是一个表示订单已创建的事件。现在我们想要发送电子邮件通知。例如,我们可以创建一个监听器,如下所示

<?php

namespace App\Service;

use App\Event\OrderCreated;
use EventSauce\EventSourcing\MessageConsumer;
use Jphooiveld\Bundle\EventSauceBundle\ConsumableTrait;
use Symfony\Component\Mailer\MailerInterface
use Symfony\Component\Mime\RawMessage;

class SendMailNotification implements MessageConsumer
{
    use ConsumableTrait;
        
    public function __construct(
        private MailerInterface $mailer,
    ) {
    }
        
    protected function applyOrderCreated(OrderCreated $event): void
    {
        $message = new RawMessage(); 

        // other code
          
        $this->mailer->send($message);
    }
}

每当创建订单时,都会调用 applyOrderCreated 方法。

消息装饰器

消息装饰器允许您向消息添加额外的大头。您创建的每个实现 EventSauce\EventSourcing\MessageDecorator 的类都将自动将您定义的标题添加到持久消息。

向上转型

向上转型器可以在事件发生变化时转换消息。您创建的每个实现 EventSauce\EventSourcing\Upcasting\Upcaster 的类都将自动使用。

重写默认服务

在包中使用的所有服务实际上都是真实实现的别名。如果您想重写服务,只需创建自己的服务,并在您的 Kernel 中的构建方法中重写别名即可。

请注意,如果您开始重写服务,则可能会出现错误,因为自动配置使用了大量的默认实现。

假设您想要创建自己的类变体器,名为 App\EventSourcing\UnderscoreInflector,它实现了接口 EventSauce\EventSourcing\ClassNameInflector。您需要做的唯一一件事是在 Kernel 的构建方法中设置别名,其他相关服务将自动使用它。

<?php

namespace App;

use App\EventSourcing\UnderscoreInflector;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
    protected function build(ContainerBuilder $container)
    {
        $container->setAlias('jphooiveld_eventsauce.inflector', UnderscoreInflector::class);
    }
    
    // other code
}

从 1.x 版本升级

当升级到本包的 2.x 版本时,您必须安装 EventSauce 项目中的正确 Doctrine 消息存储库包。

message_repository 配置下添加了一个名为 table_schema 的新选项。如果您想与当前数据库保持向后兼容,则需要将其设置为 legacy

您可以从服务配置中删除对聚合存储库的任何绑定,因为该包已经在编译过程中通过 registerAliasForArgument 方法为您配置了这些内容。以下是我们订单聚合的示例。

services:
    _defaults:
        bind:
            # Line below here is no longer needed, compiler pass will take care of it
            # EventSauce\EventSourcing\AggregateRootRepository $orderRepository: '@jphooiveld_eventsauce.aggregate_repository.order'

某些服务配置已更改。因此,如果您手动覆盖了任何内容,您必须检查该配置。

为了升级您的代码,EventSauce 提供了一个 rector 包。有关 Rector 的更多信息,请参阅 https://github.com/EventSaucePHP/RectorFrom0to1。在 https://github.com/rectorphp/rector 上了解有关 Rector 的更多信息。

许可协议

本包受 MIT 许可协议的约束。请参阅包中的完整许可协议 https://github.com/jphooiveld/EventSauceBundle/blob/HEAD/LICENSE