I create a class that allow use dependency injection in controller method.
Implementation based in ApplicationStrategy:
namespace MyApp\Modules\Application\Route\Strategy;
use League\Route\Route;
use League\Route\Strategy\ApplicationStrategy as LeagueApplicationStrategy;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class ApplicationStrategy extends LeagueApplicationStrategy
{
/**
* {@inheritdoc}
* @throws \ReflectionException
*/
public function invokeRouteCallable(Route $route, ServerRequestInterface $request): ResponseInterface
{
$controller = $route->getCallable($this->getContainer());
$reflection = new \ReflectionMethod($controller[0], $controller[1]);
$methodParams = $reflection->getParameters();
// Initialize the array of resolved method dependencies
$resolvedParams = [
$request,
$route->getVars(),
];
// Remove two first params from array of the method dependencies to resolution
// because the two first it's already resolved and defined in $resolvedParams initialization
$methodParams = array_slice($methodParams, 2);
// Resolve the dependencies
foreach ($methodParams as $methodParam) {
if ($methodParam->getClass()) {
$resolvedParams[] = $this->getContainer()->get($methodParam->getClass()->getName());
} else {
$resolvedParams[] = $this->getContainer()->get($methodParam->getName());
}
}
// Call the method
$response = $controller(...$resolvedParams);
$response = $this->applyDefaultResponseHeaders($response);
return $response;
}
}
In definition of route strategy, replace this:
$strategy = (new League\Route\Strategy\ApplicationStrategy())->setContainer($container); // default implementation
$router = (new League\Route\Router)->setStrategy($strategy);
to this:
$strategy = (new MyApp\Modules\Application\Route\Strategy\ApplicationStrategy())->setContainer($container); // custom implementation
$router = (new League\Route\Router)->setStrategy($strategy);
class UserController
{
protected $userService;
nction __construct(UserService $userService)
{
$this->userService = $userService;
}
/**
* Your method MUST start with the request object and route params array in beginning,
* after that, you are free to use the dependency inject as you wish.
*/
public function find(ServerRequestInterface $request, array $routeParams, UserService $IcanInjectUserServiceHereToo)
{
// ...
}
}
I create a class that allow use dependency injection in controller method.
Implementation based in ApplicationStrategy:
In definition of route strategy, replace this:
to this:
Example route:
Example controller: