Laravel: Как работает внедрение зависимостей с подсказкой типов?
Если кто-то использует в контроллере что-то вроде
class ContactController extends Controller
{
public function send(Request $request)
{
//...
тогда всякий раз, когда функция send()
вызывается без ввода, Laravel автоматически разрешит Request
объект из сервисного контейнера. Но где и как происходит это волшебство?
Я проверил абстрактный класс Illuminate\Routing\Controller
который имеет только 4 метода, и ни одна из тем, кажется, не добивается цели. Я также заметил, что если я сделаю что-то вроде
class ContactController
{
public function send(Request $request)
{
//...
тогда всякий раз, когда звонит send()
это бросит Too few arguments to function..
ошибка.
Я не знаю, где еще искать. Если я загадаю свой вопрос, я найду много постов, объясняющих, как использовать type hint
но не как это на самом деле работает.
Так где же фрагмент кода, который разрешает объект из сервисного контейнера, если я напишу подсказку в контроллере?
1 ответ
На самом деле он не использует контейнер для вызова вашего метода контроллера, как ни странно, даже если сам контроллер разрешен из контейнера (что даст вам инъекцию конструктора из контейнера)
Illuminate\Routing\Route@run
-> runController()
->
Illuminate\Routing\ControllerDispatcher
использования Illuminate\Routing\RouteDependencyResolverTrait
resolveClassMethodDependencies() -> resolveMethodDependencies()
... во время этого процесса контейнер используется для разрешения экземпляров для зависимостей, которые были собраны прямым отражением.
ControllerDispatcher
заканчивается вызовом вашего метода и передачей ему разрешенных параметров.
Он делает то, что кажется похожим на контейнер call
метод.