ajgl / simple-bus-query-bus
simple-bus/message-bus 的扩展,用于创建查询总线。
Requires
- php: >=7.4
- simple-bus/message-bus: ^6
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.8
- phpunit/phpunit: ^9
This package is auto-updated.
Last update: 2024-09-04 16:04:32 UTC
README
此包是 @matthiasnoback 的 MessageBus 包的扩展,旨在构建查询总线。
它允许您创建一个消息总线,该总线将捕获给定消息处理程序的返回值。
安装
要安装此组件的最新稳定版本,请打开控制台并执行以下命令
$ composer require ajgl/simple-bus-query-bus
用法
实现查询总线
此包中的类和接口可用于设置查询总线。查询总线的特点是
- 处理查询,即询问消息
- 查询由恰好一个查询处理程序处理
- 查询总线的功能可扩展:中间件可以在处理查询前后执行操作
- 要获取查询结果,必须将第二个参数传递给查询总线以填充查询结果。
设置查询总线
至少需要一个 CatchReturnMessageBusSupportingMiddleware
实例
use Ajgl\SimpleBus\Message\Bus\Middleware\CatchReturnMessageBusSupportingMiddleware; $query = new CatchReturnMessageBusSupportingMiddleware();
定义查询处理程序映射
现在我们还想让查询由恰好一个查询处理程序(可以是任何 可调用)处理。我们首先需要定义应用程序中可用的处理程序集合。我们应该使这个 查询处理程序映射 懒加载,这样即使不使用,也不会加载所有查询处理程序
use SimpleBus\Message\CallableResolver\CallableMap; use SimpleBus\Message\CallableResolver\ServiceLocatorAwareCallableResolver; // Provide a map of query names to callables. You can provide actual callables, or lazy-loading ones. $queryHandlersByQueryName = [ 'Fully\Qualified\Class\Name\Of\Query' => ... // a "callable" ];
提供的每个 "可调用" 可以是以下任何一种
- 实际的 PHP 可调用,
- 一个服务 ID(字符串),服务定位器(见下文)可以解析为 PHP 可调用,
- 一个数组,其第一个值是一个服务 ID(字符串),服务定位器可以解析为常规对象,第二个值是方法名称。
为了与向后兼容,具有 handle()
方法的对象也计为 "可调用"。
// Provide a service locator callable. It will be used to instantiate a handler service whenever requested. $serviceLocator = function ($serviceId) { $handler = ...; return $handler; } $queryHandlerMap = new CallableMap( $queryHandlersByQueryName, new ServiceLocatorAwareCallableResolver($serviceLocator) );
解析查询处理程序以查询名称
查询名称
首先,我们需要一种方法来解析查询的名称。您可以使用查询对象的完全限定类名(FQCN)作为其名称
use SimpleBus\Message\Name\ClassBasedNameResolver; $queryNameResolver = new ClassBasedNameResolver();
或者您可以询问查询对象它们的名称是什么
use SimpleBus\Message\Name\NamedMessageNameResolver; $queryNameResolver = new NamedMessageNameResolver();
在这种情况下,您的查询必须实现 NamedMessage
use SimpleBus\Message\Name\NamedMessage; class YourQuery implements NamedMessage { public static function messageName() { return 'your_query'; } }
实现自己的
MessageNameResolver
如果您想使用其他规则来确定查询的名称,请创建一个实现
SimpleBus\Message\Name\MessageNameResolver
的类。
根据查询名称解析查询处理程序
使用您选择的 MessageNameResolver
,现在您可以让 查询处理程序解析器 为给定查询找到正确的查询处理程序。
use SimpleBus\Message\Handler\Resolver\NameBasedMessageHandlerResolver; $queryHandlerResolver = new NameBasedMessageHandlerResolver( $queryNameResolver, $queryHandlerMap );
最后,我们应该向查询总线添加一些中间件,该中间件调用解析的查询处理程序并捕获处理程序的结果
use Ajgl\SimpleBus\Message\Handler\DelegatesToMessageHandlerAndCatchReturnMiddleware; $queryBus->appendMiddleware( new DelegatesToMessageHandlerAndCatchReturnMiddleware( $queryHandlerResolver ) );
使用查询总线:一个示例
考虑以下查询
class FindUserByEmailAddress { private $emailAddress; public function __construct($emailAddress) { $this->emailAddress = $emailAddress; } public function emailAddress() { return $this->emailAddress; } }
此查询传达了“通过电子邮件地址查找用户”的意图。消息数据包含电子邮件地址。这些信息是执行所需行为所必需的。
此查询的处理程序如下所示
class FindUserByEmailAddressQueryHandler { ... public function handle(FindUserByEmailAddress $query) { $user = $this->userRepository->findOneByEmailAddress( $query->emailAddress() ); return $user; } }
我们应该将此处理器注册为服务,并将服务ID添加到查询处理器映射中。由于我们已完全配置了查询总线,我们可以开始创建一个新的查询对象,并让查询总线处理它。最终,查询将作为消息传递给FindUserByEmailAddressQueryHandler
。
$query = new FindUserByEmailAddress( 'aj@garcialagar.es' ); $queryBus->handle($query, $queryResult);
处理完查询后,$queryResult
变量将包含查询结果(找到的用户)。
许可证
此组件受MIT许可证的约束。请参阅LICENSE文件中的完整许可证。
报告问题或功能请求
问题和功能请求在GitHub问题跟踪器中进行跟踪。
作者信息
如果您觉得此组件有用,请在该GitHub存储库页面和/或Packagist软件包页面添加一个★。