首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony战术家-包类型提示=缺少处理程序方法错误

Symfony战术家-包类型提示=缺少处理程序方法错误
EN

Stack Overflow用户
提问于 2018-09-15 12:55:03
回答 1查看 1K关注 0票数 1

我以前在Symfony中使用过thephpleague/tactician,但这是我第一次在Symfony 4.* (特别是4.1.4)中使用它,并试图为我的应用程序服务使用一个处理程序类。

当我在Controller中执行命令时

代码语言:javascript
复制
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;
}

..。我得到以下错误:

代码语言:javascript
复制
"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安装指南,注册了该包,并安装了配置包:

代码语言:javascript
复制
tactician:
    commandbus:
        default:
            middleware:
                - tactician.middleware.locking
                - tactician.middleware.doctrine
                - tactician.middleware.command_handler

在创建了DTO命令类'CreateVenueCommand‘之后,我创建了处理程序类:

代码语言:javascript
复制
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的自动装配和战术人员的输入提示:

代码语言:javascript
复制
    App\Application\VenueApplicationService:
        arguments:
            - '@App\Infrastructure\Persistence\Doctrine\DoctrineVenueRepository'
        tags:
           - { name: tactician.handler, typehints: true }

因此,根据安装文件,类型提示的工作条件是:

  1. 方法必须是公开的。
  2. 该方法只能接受一个参数。
  3. 必须键入带有类名的参数。

而且,这也是特定于我的用例的:

如果在单个处理程序中有多个命令,那么只要它们遵循上述规则,它们都会被检测到。方法的实际名称并不重要。

因此,当我在Controller类中调用命令总线时,我不知道为什么会出现上述错误。

如果我将方法更改为:

代码语言:javascript
复制
public function handle(CreateVenueCommand $aCommand)
{

..。那它就能正常工作。这似乎表明,类型提示并不像文档所描述的那样有效。

在这种情况下,方法的实际名称似乎是重要。.或者我在我的实现中犯了一些错误.或者我误解了多个命令进入单个处理程序用例?

如能提供任何协助,将不胜感激。

解决方案

非常感谢kunicmarko20为我指明了正确的方向。

特别是对于我的用例,我只需要使用一个战术家MethodNameInflector类,在Symfony中配置如下:

代码语言:javascript
复制
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方法

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-15 19:49:12

1.下面的这里解释了命名的工作原理,如果您想使用与本表中不同的名称,则可以实现MethodNameInflector接口并提供方法的名称。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52344901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档