Я использовал пакет thephpleague / tactician-bundle с Symfony и раньше, но впервые я использовал его с 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": [
Я, кажется, следовал за установочные документы для комплекта поставки и установки его с помощью Flex.Насколько я могу судить, все настроено правильно, поэтому я не уверен, что мне не хватает в моей реализации.
Реализация
Согласно руководству по установке комплекта thephpleague / tactician-bundle I 'После установки с использованием Flex, пакет зарегистрирован и установлен пакет конфигурации:
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 }
Таким образом, согласно установочным документам , шрифты работают, если:
- Метод должен быть общедоступным.
- Метод должен принимать только один параметр.
- Параметр должен быть напечатан с именем класса.
Кроме того, и это характерно для моего случая использования:
Если у вас есть несколько команд, поступающих в один обработчик, они все будут обнаружены, если они следуютправила выше.Фактическое имя метода НЕ важно.
Поэтому, когда я вызываю командную шину в классе контроллера, я не уверен, почему я получаю ошибку выше.
Если я изменю метод обработчика команд на:
public function handle(CreateVenueCommand $aCommand)
{
... тогда он будет работать нормально.Казалось бы, это говорит о том, что шрифты не работают так, как задокументировано.
В данном случае кажется, что фактическое имя метода IS важно. ... или я допустил какую-то форму ошибки в моей реализации ..или я неправильно понимаю несколько команд, входящих в один обработчик сценарий использования ??
Любая помощь будет принята с благодарностью.
Решение
Большое спасибо kunicmarko20 за то, что он указал мне правильное направление.
Специально для моего использованияслучай, когда мне просто нужно было использовать один из классов Tacticians 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
... тогда это был просто вопрос присвоения имен каждому методу Handler в дескрипторе моего класса Application Service 'Команда