mikemix/tactician-module

Laminas/Mezzio 模块,用于在您的 Laminas 或 Mezzio 应用中使用 League of Extraordinary Packages 的 Tactician 库 - 灵活的命令总线实现

3.3.0 2024-03-04 09:47 UTC

README

包装模块,便于在您的 Laminas 或 Mezzio 应用中使用 Tactician 命令总线。

Build Status Scrutinizer Code Quality Code Coverage Latest Stable Version Total Downloads License

安装

最佳安装方式为使用 Composer

composer require mikemix/tactician-module

在您的 config/application.config.php 文件中将 TacticianModule 注册为 Laminas 框架模块。

您还可以通过 TacticianModule\ConfigProvider 将此包用作 Mezzio 模块。

使用

该模块提供了一个名为 Controller PlugintacticianCommandBus(),用于轻松分发命令。如果没有传递命令对象,则返回 CommandBus 对象。如果您传递了命令,它将被传递给 CommandBus 并处理,处理程序的输出将返回。

您可以在控制器中为该插件提供类型提示,例如:@method \League\Tactician\CommandBus|mixed tacticianCommandBus(object $command)

// Real life example.
// Namespaces, imports, class properties skipped for brevity

class LoginController extends AbstractActionController
{
    public function indexAction()
    {
        if ($this->request->isPost()) {
            $this->form->setData($this->request->getPost());

            if ($this->form->isValid()) {
                $command = new UserLoginCommand(
                    $this->form->getLogin(),
                    $this->form->getPassword()
                ));

                try {
                    $this->tacticianCommandBus($command);
                    return $this->redirect()->toRoute('home');
                } catch (\Some\Kind\Of\Login\Failure $exception) {
                    $this->flashMessenger()->addErrorMessage($exception->getMessage());
                    return $this->redirect()->refresh();
                }
            }
        }

        $view = new ViewModel();
        $view->setVariable('form', $this->form);
        $view->setTemplate('app/login/index');

        return $view;
    }
}

final class UserLoginCommand
{
    public function __construct($login, $password)
    {
        $this->login = $login;
        $this->password = $password;
    }
}

final class UserLoginHandler
{
    // constructor skipped for brevity

    public function handle(UserLoginCommand $command)
    {
        $this->authenticationService->login($command->username, $command->password);
    }
}

您可以通过工厂请求 Container 中的 League\Tactician\CommandBus::class 来将 CommandBus 注入到您的服务层。

配置

该模块默认配备了 LaminasLocatorCommandHandlerMiddlewareHandlerInflector。如果您想覆盖默认的定位器或默认命令总线实现,则只需在合并的配置中使用 tactician 键。

'tactician' => [
    'default-extractor'  => League\Tactician\Handler\CommandNameExtractor\ClassNameExtractor::class,
    'default-locator'    => TacticianModule\Locator\LaminasLocator::class,
    'default-inflector'  => League\Tactician\Handler\HandleInflector::class,
    'handler-map'        => [],
    'middleware'         => [
        CommandHandlerMiddleware::class => 0,
    ],
],

default-extractordefault-locatordefault-inflector 是注册服务的服务管理器键。

LaminasLocator 期望在 handler-map 中的处理程序是 commandName => serviceManagerKeycommandName => Handler_FQCN,尽管为了防止额外的成本检查,请使用 serviceManagerKey 并确保它作为 Laminas 服务可用。

要向中间件栈中添加自定义中间件,请将其添加到 middleware 数组中,格式为 ServiceName => priority,其中指定了中间件的执行顺序(数字越高,执行越早)。例如

// ... your module config
'tactician' => [
    'middleware'         => [
        YourAnotherMiddleware::class => 100, // execute early
        YourCustomMiddleware::class  => 50,  // execute last
    ],
],

基本用法

基本上,您可能想要做的,就是在您模块的配置中定义 handler-map 数组。例如

// module.config.php file

    return [
        // other keys
        'tactician' => [
            'handler-map' => [
                App\Command\SomeCommand::class => App\Handler\SomeCommandHandler::class,
            ],
        ],
    ];

插件

锁定中间件

现在可以开箱即用 LockingMiddleware。只需将 League\Tactician\Plugins\LockingMiddleware FQCN 添加到 TacticianModule 的中间件配置中,并指定适当的优先级。您可能想在 CommandHandlerMiddleware 之前执行它。

// module.config.php file

    return [
        // other keys
        'tactician' => [
            'middleware' => [
                \League\Tactician\Plugins\LockingMiddleware::class => 500,
            ],
        ],
    ];

事务中间件

现在可以开箱即用 TransactionMiddleware。只需将 League\Tactician\Doctrine\ORM\TransactionMiddleware FQCN 添加到 TacticianModule 的中间件配置中,并指定适当的优先级。您可能想在 LockingMiddleware 之后和 CommandHandlerMiddleware 之前执行它。

// module.config.php file

    return [
        // other keys
        'tactician' => [
            'middleware' => [
                \League\Tactician\Doctrine\ORM\TransactionMiddleware::class => 250,
            ],
        ],
    ];

更改处理程序定位器

ClassnameLaminasLocator

此定位器简单地将单词 Handler 添加到命令的 FQCN,这样您就不需要定义任何处理程序映射。例如,如果您请求命令 App\Commands\LoginCommand,定位器将尝试从服务管理器中获取 App\Command\LoginCommandHandler

定位器可以与未在服务管理器中注册的 FQCN 一起工作,尽管为了防止额外的成本检查,请确保定位器已注册为可调用或工厂。

要将定位器从 LaminasLocator 更改为 ClassnameLaminasLocator,只需在配置中设置即可

// ... your module config
'tactician' => [
    'default-locator' => TacticianModule\Locator\ClassnameLaminasLocator::class,
],