ajgl/simple-bus-query-bus

simple-bus/message-bus 的扩展,用于创建查询总线。

0.3.0 2022-05-04 10:26 UTC

This package is auto-updated.

Last update: 2024-09-04 16:04:32 UTC


README

此包是 @matthiasnoback 的 MessageBus 包的扩展,旨在构建查询总线。

Build Status Latest Stable Version Latest Unstable Version Total Downloads Montly Downloads Daily Downloads License

它允许您创建一个消息总线,该总线将捕获给定消息处理程序的返回值。

安装

要安装此组件的最新稳定版本,请打开控制台并执行以下命令

$ 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问题跟踪器中进行跟踪。

作者信息

Antonio J. García Lagar开发。

如果您觉得此组件有用,请在该GitHub存储库页面和/或Packagist软件包页面添加一个★。