用联盟/路线将容器注入控制器

时间:2016-05-09 14:35:17

标签: php routing containers

我正在使用联盟/路线,我想将我的容器注入控制器。这就是我已经拥有的东西:

提供RouteCollection:

$this->getContainer()->share('route', function () {
    $route = require $this->getContainer()->get('baseDir').'/config/routes.php';

    return $route;
});

BASEDIR /配置/ routes.php文件:

<?php

use League\Route\Strategy\ParamStrategy;
use League\Container\ReflectionContainer;

$routes = (new \League\Route\RouteCollection)
    ->setStrategy((new ParamStrategy)->setContainer(new ReflectionContainer));
    // The line above is here because ParamStrategy otherwise throws
    // Uncaught exception 'RuntimeException' with message 'To use the parameter strategy,
    // the container must implement the (::call) method.

$routes->get('/', 'Controller\PostController::index');

return $routes;

我的前端控制器:

/** @var RouteCollection $route */
$route = $this->getContainer()->get('route');
/** @var ServerRequest $request */
$request = $this->getContainer()->get('request');
/** @var Response $response */
$response = $this->getContainer()->get('response');
/** @var SapiEmitter $emitter */
$emitter = $this->getContainer()->get('emitter');

$response = $route->dispatch($request, $response);

$emitter->emit($response);

我不知道我应该在哪里调用控制器对象上的setContainer方法,因为它只存在于$route->dispatch($request, $response);内。将该容器注入我的控制器的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

首先,这里有几点意见。

  1. 将容器注入控制器的是“服务位置”。这被认为是反模式(http://ralphschindler.com/2012/10/10/di-dic-service-locator-redux是对DI和SL之间区别的一个很好的解释)。
  2. 在您的示例中,您明确地在路径集合上设置了一个反射容器,这意味着它将专门尝试通过反射来解析依赖关系,而不是从原始容器被覆盖时设置的任何定义。
  3. 如果您坚持在控制器中使用容器,则可以在容器上使用导向器在每个控制器中实现此目的。 http://container.thephpleague.com/inflectors/ - 通过使用此链接中的方法,您可以让控制器实现ContainerAwareInterface,每当路由器解析其中一个控制器时,您就可以让容器调用传入主容器的setContainer方法。

    希望这有帮助,我目前正在度假,所以不能给出代码示例,但是一旦我回来,我会编辑这个答案。