В контексте MVC у меня есть контроллер, который зависит от службы, а служба, в свою очередь, зависит от источника данных (в конкретном случае это клиент для получения данных из стороннего API).
Чтобы создать экземпляр службы с фиктивным источником данных при тестировании, конструктор службы ожидает источник данных. То же самое относится и к контроллеру, конструктор которого ожидает службы.
При создании контроллера я также хочу передать ему объект запроса, потому что я бы предпочел это
new Controller(request, service).action_name
к этому
new Controller(service).action_name(request)
Добиться этого без использования какого-либо контейнера для внедрения зависимостей очень просто.
Чего я не понимаю, так это того, как это сделать с помощью php-di
Моя цель состоит в том, чтобы служба была внедрена в контроллер контейнером, при этом я сам передавал объект запроса контроллеру.
ОБНОВЛЕНИЕ 1
Это мой ApplicationController
namespace DEC;
class ApplicationController {
private $service;
private $request;
public function __construct(Foo $service, $request) {
$this->service= $service;
$this->request = $request;
}
public function index() {
$out = $this->service->foo();
$out .= $this->request->method();
return $out;
}
}
Фу следует
namespace DEC;
class Foo {
public function __construct() {
}
public function foo() {
return "FOO";
}
}
Это мой запрос
namespace DEC;
class Foo {
public function __construct() {
}
public function foo() {
return "FOO";
}
}
И это моя попытка заставить DI работать так, как мне бы хотелось:
$container = ContainerBuilder::buildDevContainer();
$response = $container->call([ApplicationController::class, 'index'], [
'request' => new Request('GET')
]);
echo $response;
Это ошибка, которую я получаю:
Entry "DEC\ApplicationController" cannot be resolved: Parameter $request of __construct() has no value defined or guessable
Full definition:
Object (
class = DEC\ApplicationController
scope = singleton
lazy = false
__construct(
$service = get(DEC\Foo)
$request = #UNDEFINED#
)
)
Примечание: ошибка остается прежней, если я набираю запрос и/или меняю порядок параметров в конструкторе
Глядя на ошибку, я делаю вывод, что решение ::call(), предложенное Мэтью Наполи, работает, если я создаю экземпляр контроллера только с сервисом и передаю запрос в качестве параметра для метода действия.
Означает ли это, что я не могу полагаться на контейнер для «частичной» инъекции?
ОБНОВЛЕНИЕ 2
Для решения, описанного в этом обновлении, посмотрите мой собственный ответ на вопрос