梦游者/laravel-doctrine-domain-events

此包已被废弃,不再维护。作者建议使用梦游者/domain包。

向Doctrine实体添加领域事件。

0.7.0 2017-05-21 16:02 UTC

This package is auto-updated.

Last update: 2022-02-01 13:00:26 UTC


README

该项目已被替换为一个通用的领域库,将多个包合并为一个,以便于维护。

Laravel-Doctrine ORM的领域事件

向Doctrine实体添加对领域事件的支持。此包受Benjamin Eberlei的Gist和博客文章的启发。

要求

  • PHP 5.6+
  • bcmath扩展
  • Laravel 5.2+
  • laravel-doctrine/orm

安装

使用composer安装,或从github.com检查/拉取文件。

  • composer install somnambulist/laravel-doctrine-domain-events
  • 将事件监听器添加到您的实体管理器配置中的config/doctrine.php
  • 将接口添加到您的聚合根(应引发事件的主体实体)
  • 将特里特添加以提供接口的实现(或自己编写)
  • 添加一些扩展提供的领域事件的领域事件
  • 创建一些监听器并将它们附加到doctrine配置中的领域事件

包含一个服务提供者,它添加了编译功能,允许将主要类添加到主要引导中。

  • 注意:DomainEventListener应根据实体管理器实例进行配置。

引发事件

要引发事件,请决定哪些操作应导致领域事件。这些应与领域对象的州变化相一致,并且事件应来自您的主体实体(聚合根)。

例如:您可能希望在创建新的User实体或向用户添加角色时引发事件。

这确实需要更改您通常与实体和Doctrine一起工作的方式,您应该删除设置器和可空的构造函数参数。相反,您将需要通过特定方法来管理对实体更改,例如

  • completeOrder()
  • updatePermissions()
  • revokePermissions()
  • publishStory()

内部,在更新实体状态后,调用:$this->raise(new NameOfEvent([]))并将任何特定的参数传递到事件中,您希望使监听器可用。这可能是旧的和新的,或者是整个实体引用,完全取决于您。

public function __construct($id, $name, $another, $createdAt)
{
    $this->id        = $id;
    $this->name      = $name;
    $this->another   = $another;
    $this->createdAt = $createdAt;
    $this->raise(new MyEntityCreatedEvent(['id' => $id, 'name' => $name, 'another' => $another]));
}

通常,在构造函数中不引发事件更好,而是使用命名构造函数进行主要对象的创建。

private function __construct($id, $name, $another, $createdAt)
{
    $this->id        = $id;
    $this->name      = $name;
    $this->another   = $another;
    $this->createdAt = $createdAt;
    $this->raise(new MyEntityCreatedEvent(['id' => $id, 'name' => $name, 'another' => $another]));
}

public static function create($id, $name, $another)
{
    $entity = new static($id, $name, $another, new DateTime());
    $entity->raise(new MyEntityCreatedEvent(['id' => $id, 'name' => $name, 'another' => $another]));
    
    return $entity;
}

触发领域事件

此实现包括一个Doctrine订阅者,它将监听实现RaisesDomainEvent接口的实体,并确保调用releaseAndResetEvents()

  • 注意:在v.0.6之前,订阅者监听生命周期事件,如果聚合根没有被同时修改,可能会错过事件。

  • 注意:不需要使用DomainEventListener订阅者。你可以实现自己的事件分发器,完全使用另一个分发器(框架)然后手动通过刷新更改并手动调用releaseAndResetEvents来触发领域事件。

    如果你这样做,请注意聚合根类和主标识符(如果使用)将不会自动设置。如果你打算使用它们,需要更新你的代码来设置这些。

要使用包含的监听器,将其添加到Doctrine配置中的事件订阅者列表。这是针对每个实体管理器。

  • 注意:要使用依赖于Doctrine存储库的领域事件的监听器,需要在Doctrine解决之后延迟加载这些订阅者。在Laravel中,这可以在服务提供者的boot方法中完成。请参阅Laravel Doctrine项目中的示例延迟加载器。

创建领域事件监听器

监听器可以有它们自己的依赖(构造函数未定义),并在onFlush单元工作事件之后被调用。监听器可以执行任何必要的后处理,甚至触发更多事件。

监听器应该添加名为

  • onNameOfTheEvent
  • 的方法,不附加"event"后缀
  • 该方法将接收领域事件实例
  • 领域事件将具有聚合根的类和id

单元测试的示例

class EventListener
{    
    public function onMyEntityCreated(MyEntityCreatedEvent $event)
    {
        printf(
            "New item created with id: %s, name: %s, another: %s",
            $event->getProperty('id'),
            $event->getProperty('name'),
            $event->getProperty('another')
        );
    }
}

单元测试显示了如何实现它。

务必阅读前面提到的Benjamin Eberlei的文章,并查看他的断言库,用于低依赖项实体验证。

或者,对于挂钩到Laravel主要验证器的验证,请参阅:Laravel Doctrine实体验证

链接