commandNameExtractor = $commandNameExtractor; $this->handlerLocator = $handlerLocator; $this->methodNameInflector = $methodNameInflector; } /** * Executes a command and optionally returns a value * * @param object $command * @param callable $next * * @return mixed * * @throws CanNotInvokeHandlerException */ public function execute($command, callable $next) { $commandName = $this->commandNameExtractor->extract($command); $handler = $this->handlerLocator->getHandlerForCommand($commandName); $methodName = $this->methodNameInflector->inflect($command, $handler); // is_callable is used here instead of method_exists, as method_exists // will fail when given a handler that relies on __call. if (!is_callable([$handler, $methodName])) { throw CanNotInvokeHandlerException::forCommand( $command, "Method '{$methodName}' does not exist on handler" ); } return $handler->{$methodName}($command); } }