Symfony Tactician-bundle Typehints = 缺少处理程序方法错误
Posted
技术标签:
【中文标题】Symfony Tactician-bundle Typehints = 缺少处理程序方法错误【英文标题】:Symfony Tactician-bundle Typehints = Missing handler method error 【发布时间】:2019-02-20 00:43:23 【问题描述】:我之前在 Symfony 中使用过 thephpleague/tactician-bundle,但这是我第一次在 Symfony 4.*(特别是 4.1.4)中使用它,并尝试为我的应用程序使用单个处理程序类服务。
当我在控制器中执行命令时
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": [
我似乎遵循了 installation documents 的 tactician-bundle 并使用 Flex 安装了它。据我所知,一切都配置正确,所以我不确定我的实现中缺少什么。
实施
根据我使用 Flex 安装的 thephpleague/tactician-bundle 安装指南,并注册了捆绑包并安装了配置包:
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 的自动装配和 Tacticians 类型提示将处理程序类注册为服务:
App\Application\VenueApplicationService:
arguments:
- '@App\Infrastructure\Persistence\Doctrine\DoctrineVenueRepository'
tags:
- name: tactician.handler, typehints: true
所以根据installation documents,类型提示在以下情况下起作用:
方法必须是公开的。 该方法只能接受一个参数。 参数必须使用类名进行类型提示。
另外,这是针对我的用例的:
如果您有多个命令进入一个处理程序,只要它们遵循上述规则,它们都会被检测到。方法的实际名称并不重要。
所以当我在控制器类中调用命令总线时,我不确定为什么会出现上述错误。
如果我将命令处理程序方法更改为:
public function handle(CreateVenueCommand $aCommand)
...然后它工作正常。这似乎表明 typehints 没有按记录工作。
在这种情况下,方法的实际名称IS似乎很重要。 ...或者我在实现中犯了某种形式的错误...或者我误解了多个命令进入单个处理程序用例??
任何帮助将不胜感激。
解决方案
非常感谢 kunicmarko20 为我指明了正确的方向。
特别是对于我的用例,我只需要使用在 Symfony 中配置的 Tacticians MethodNameInflector 类之一:
tactician:
commandbus:
default:
middleware:
- tactician.middleware.locking
- tactician.middleware.doctrine
- tactician.middleware.command_handler
method_inflector: tactician.handler.method_name_inflector.handle_class_name
...那么只需在我的应用程序服务类 'handlewhateverYouLikeCommand
中命名每个 Handler 方法即可【问题讨论】:
【参考方案1】:1. 下的Here 解释了命名的工作原理,如果您想使用与此表中不同的名称,您可以实现 MethodNameInflector 接口并提供方法的名称。
【讨论】:
以上是关于Symfony Tactician-bundle Typehints = 缺少处理程序方法错误的主要内容,如果未能解决你的问题,请参考以下文章
Symfony 2 还是 Symfony 1.4? [关闭]
symfony/skeleton 和 symfony/website-skeleton