Инъекция контейнера в контроллер с лигой / маршрутом

Я использую лигу / маршрут и хочу ввести свой контейнер в контроллер. Вот что у меня уже есть:

Предоставление 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);, Как правильно ввести этот контейнер в мой контроллер?

0

Решение

Итак, пара моментов здесь в первую очередь.

  1. Внедрение контейнера в ваш контроллер — это расположение службы. Это считается анти паттерном (http://ralphschindler.com/2012/10/10/di-dic-service-locator-redux является хорошим объяснением различия между DI и SL).
  2. В ваших примерах вы явно устанавливаете контейнер отражений в коллекции маршрутов, это означает, что он будет пытаться разрешить зависимости исключительно посредством отражения, а не из каких-либо определений, которые вы могли установить, поскольку этот исходный контейнер перезаписывается.

Если вы настаиваете на использовании контейнера в вашем контроллере, вы можете использовать инфлектор на контейнере для достижения этого в каждом контроллере. http://container.thephpleague.com/inflectors/ — используя метод, приведенный в этой ссылке, вы можете заставить свои контроллеры реализовывать ContainerAwareInterface, и всякий раз, когда маршрутизатор разрешает один из этих контроллеров, вы можете заставить контейнер вызывать метод setContainer, передаваемый в ваш основной контейнер.

Надеюсь, это поможет, я сейчас в отпуске, поэтому не могу привести примеры кода, но я отредактирую этот ответ, как только вернусь.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector