mikemix / tactician-module
Laminas/Mezzio 模块,用于在您的 Laminas 或 Mezzio 应用中使用 League of Extraordinary Packages 的 Tactician 库 - 灵活的命令总线实现
Requires
- php: ^7.1 || ^8.0
- league/tactician: ^1.0
- psr/container: ^1.0 || ^2.0
Requires (Dev)
- doctrine/orm: ^2.5
- laminas/laminas-mvc: ^3.1.1
- league/tactician-doctrine: ^1.0
- phpunit/phpunit: ^7.5.20 || ^9.3.8
- squizlabs/php_codesniffer: ^3.6
This package is auto-updated.
Last update: 2024-09-04 10:53:30 UTC
README
包装模块,便于在您的 Laminas 或 Mezzio 应用中使用 Tactician 命令总线。
安装
最佳安装方式为使用 Composer
composer require mikemix/tactician-module
在您的 config/application.config.php
文件中将 TacticianModule
注册为 Laminas 框架模块。
您还可以通过 TacticianModule\ConfigProvider
将此包用作 Mezzio 模块。
使用
该模块提供了一个名为 Controller Plugin 的 tacticianCommandBus()
,用于轻松分发命令。如果没有传递命令对象,则返回 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
注入到您的服务层。
配置
该模块默认配备了 LaminasLocator
、CommandHandlerMiddleware
和 HandlerInflector
。如果您想覆盖默认的定位器或默认命令总线实现,则只需在合并的配置中使用 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-extractor
、default-locator
和 default-inflector
是注册服务的服务管理器键。
LaminasLocator
期望在 handler-map
中的处理程序是 commandName => serviceManagerKey
或 commandName => 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, ],