我以前在Symfony中使用过thephpleague/tactician,但这是我第一次在Symfony 4.* (特别是4.1.4)中使用它,并试图为我的应用程序服务使用一个处理程序类。
当我在Controller中执行命令时
public function postAction(Request $request, CommandBus $commandBus)
{
$form = $this->createForm(VenueType::class);
$form->submit($request->request->all(), true);
$data = $form->getData();
if($form->isValid()) {
$command = new CreateVenueCommand($data);
$commandBus->handle($command);
return $form->getData();
}
return $form;
}..。我得到以下错误:
"error": {
"code": 500,
"message": "Internal Server Error",
"exception": [
{
"message": "Could not invoke handler for command App\\Application\\Command\\CreateVenueCommand for reason: Method 'handle' does not exist on handler",
"class": "League\\Tactician\\Exception\\CanNotInvokeHandlerException",
"trace": [我似乎跟踪了战术包的安装文件,并使用Flex安装了它。据我所知,一切都是正确配置的,所以我不确定我在实现中缺少了什么。
实现
根据使用Flex安装的thephpleague/tactician安装指南,注册了该包,并安装了配置包:
tactician:
commandbus:
default:
middleware:
- tactician.middleware.locking
- tactician.middleware.doctrine
- tactician.middleware.command_handler在创建了DTO命令类'CreateVenueCommand‘之后,我创建了处理程序类:
use App\Infrastructure\Domain\Model\VenueRepositoryInterface;
use App\Application\Command\CreateVenueCommand;
use App\Domain\Entity\Venue;
class VenueApplicationService
{
private $venueRepository;
public function __construct(VenueRepositoryInterface $venueRepository)
{
$this->venueRepository = $venueRepository;
}
/**
* @param CreateVenueCommand $aCommand
* @throws \Exception
*/
public function createVenue(CreateVenueCommand $aCommand)
{
$aVenue = new Venue($aCommand->getData())
if ($aVenue === null) {
throw new \LogicException('Venue not created');
}
$this->venueRepository->add($aVenue);
}然后,我将处理程序类注册为一个服务,利用Symfony的自动装配和战术人员的输入提示:
App\Application\VenueApplicationService:
arguments:
- '@App\Infrastructure\Persistence\Doctrine\DoctrineVenueRepository'
tags:
- { name: tactician.handler, typehints: true }因此,根据安装文件,类型提示的工作条件是:
而且,这也是特定于我的用例的:
如果在单个处理程序中有多个命令,那么只要它们遵循上述规则,它们都会被检测到。方法的实际名称并不重要。
因此,当我在Controller类中调用命令总线时,我不知道为什么会出现上述错误。
如果我将方法更改为:
public function handle(CreateVenueCommand $aCommand)
{..。那它就能正常工作。这似乎表明,类型提示并不像文档所描述的那样有效。
在这种情况下,方法的实际名称似乎是重要。.或者我在我的实现中犯了一些错误.或者我误解了多个命令进入单个处理程序用例?
如能提供任何协助,将不胜感激。
解决方案
非常感谢kunicmarko20为我指明了正确的方向。
特别是对于我的用例,我只需要使用一个战术家MethodNameInflector类,在Symfony中配置如下:
tactician:
commandbus:
default:
middleware:
- tactician.middleware.locking
- tactician.middleware.doctrine
- tactician.middleware.command_handler
method_inflector: tactician.handler.method_name_inflector.handle_class_name..。然后简单地命名我的应用程序服务类句柄{whateverYouLike}命令中的每个Handler方法
发布于 2018-09-15 19:49:12
1.下面的这里解释了命名的工作原理,如果您想使用与本表中不同的名称,则可以实现MethodNameInflector接口并提供方法的名称。
https://stackoverflow.com/questions/52344901
复制相似问题