studioignis / evt
轻松在项目中实现领域事件
Requires
- php: >=5.4
- illuminate/support: ~4.1
Requires (Dev)
- illuminate/container: ~4.1
- phpspec/phpspec: ~2.1@dev
This package is not auto-updated.
Last update: 2024-09-10 02:12:28 UTC
README
StudioIgnis Evt
轻松在项目中实现领域事件。
最初受laracasts/commander启发
安装
通过composer添加包到您的composer.json文件中安装
{ "require": { "studioignis/evt": "~1.0" } }
或者使用以下命令
$ composer require studioignis/evt:~1.0
用法
非常简单,您只需要事件调度程序实例,然后就可以开始添加监听器了
$dispatcher = new StudioIgnis\Evt\EventDispatcher; $dispatcher->addListener( 'UserWasRegistered', new SendEmailUponUserRegistration($mailer) );
之后,您就可以开始调度事件了
$dispatcher->dispatch([new Acme\Events\UserWasRegistered($name, $email)]);
您可以一次性调度多个事件,这就是为什么dispatch()
需要一个事件数组的原因。
事件
事件是简单的DTO(数据传输对象),但应遵守StudioIgnis\Evt\Event
契约。此契约只声明一个方法:getEventName()
,用于获取事件的名称,以确定要运行哪些监听器。
提供了一个特质,它使用简单的默认策略满足此契约。如果您的活动是Acme\Events\UserWasRegistered
,则特质的getEventName()
将使用事件类的短名称作为事件名称,即UserWasRegistered
。
以下是一个示例
namespace Acme\Events; use StudioIgnis\Evt\Event; use StudioIgnis\Evt\Traits\EventName; class UserWasRegistered implements Event { use EventName; private $name; private $email; public function __construct($name, $email) { $this->name = $name; $this->email = $email; } public function getName() { return $this->name; } public function getEmail() { return $this->email; } }
如果我们没有使用EventName特质,我们就必须添加一个返回事件名称的getEventName()
方法。您不需要使用特质,它只是方便,您可能需要提供一个自定义名称,在这种情况下您就不会使用它。
监听器
事件监听器是一个应该遵守事件监听器契约的类。此契约定义了一个方法:handle(Event $event)
,它期望接收已调度的事件。
namespace Acme\Events; use StudioIgnis\Evt\EventListener; class SendEmailUponUserRegistration implements EventListener { private $mailer; public function __construct($mailer) { // Your hypothetical mailer class $this->mailer = $mailer; } public function handle(Event $event) { $this->mailer->sendWelcomeEmail($event->getEmail(), $event->getName()); } }
我知道,我知道,每个人都使用相同的示例,请原谅我缺乏创意 :D
在调度时解析监听器
您可以通过传递字符串抽象而不是传递已实例化的监听器
$dispatcher->addListener('SomeEvent', 'Acme\Events\SomeListener'); // or $dispatcher->addListener('SomeEvent', 'listeners.some_event_listener');
这样,监听器将在事件被调度时被实例化。
但是,为了实现这一点,调度器必须与应用程序容器一起创建
$dispatcher = new Dispatcher($container);
容器必须遵守\StudioIgnis\Evt\Support\Container
契约。
为Laravel应用程序提供了一个默认容器,因此当从IoC容器中解析调度器时,这将自动完成。
从您的实体中引发事件
您很可能会从您的实体中引发事件。为此,您有方便的HasDomainEvents特质。
此特质添加了两个方法:raise(Event $event)
和releaseEvents()
。如名称所示,raise(Event $event)
添加待调度的事件。 releaseEvents()
返回引发的事件并清除待处理的事件。
让我们看看一个示例
namespace Acme; use StudioIgnis\Evt\Traits\HasDomainEvents; class User implements EventListener { use HasDomainEvents; public function __construct($name, $email) { // Init your params, invariants, etc $this->raise(new Events\UserWasRegistered($name, $email)); } }
现在(可能在命令处理程序类中)您可以这样做
$dispatcher->dispatch($user->releaseEvents());
Laravel集成
此包包含Laravel框架的供应商。您需要将其添加到您的config/app.php
文件中
'StudioIgnis\Evt\Laravel\ServiceProvider'
这样,您可以将其作为依赖项注入,并将从IoC容器中自动解析出来
class SomeController extends Controller { private $dispatcher; public function __construct(Dispatcher $dispatcher) { $this->dispatcher = $dispatcher; } }
主要好处,如前所述,是将容器传递给调度器,这使得您可以将抽象作为监听器传递以从容器中解析。
替换调度器
如果您需要使用自己的自定义调度器,您可以在配置中更改它。为此,您需要发布此包的配置
$ php artisan config:publish studioignis/evt
并将'dispatcher'键更改为指向您的调度器类。
return [ /** * Which concrete dispatcher implementation to map to * StudioIgnis\Evt\Dispatcher contract. */ 'dispatcher' => 'StudioIgnis\Evt\EventDispatcher', ];
许可证
版权(c)2014 Luciano Longo
本软件及其相关文档文件(以下简称“软件”)的副本的任何个人,在此免费获得授权,不受限制地处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件的副本,并允许软件提供者进行此类操作,但须遵守以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“原样”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于适销性、适用于特定目的和非侵权性保证。在任何情况下,作者或版权持有人不对任何索赔、损害或其他责任承担责任,无论该责任是基于合同、侵权或其他原因,是否与软件或其使用或其他相关活动有关。