Не могу понять конструкции работы контейнера зависимостей... может кто объяснит на пальцах. а лучше примерами кода.
Играясь с ларавелем, применял такую конструкцию
class HomeController {
public function index (Request $request){
//
}
}
Т.е. в класс контроллера внедряется объект Request. Окей
Не совсем понимаю, как это происходит внутри и как такое реализуется вне фреймворка. Интернеты привели к контейнерам. Возьмем для примера Pimple. Создаем с его помощью контейнер:
use Pimple\Container;
$container = new Container();
//элемент контейнера, который при обращении вернет экземпляр Request
$container['request'] = function ($c) {
return new Request;
};
А дальше...
Да, я понимаю, что я могу засунуть в контейнер и контроллер, но.....
$container['controller'] = function ($c) {
return new HomeController($c['request']);
};
В таком случае, при обращении к $container['controller'] я получу объект HomeController, с внедренным в его конструктор Request
ну или даже так:
$container['controller'] = function ($c) {
$controller = new HomeController;
$controller->index($c['request']);
return $controller;
};
в этом случае я тоже получу объект класса, а при его создании будет запрошен метод index(), которому будет передан объект Request.
Но не пихать же в контейнер все возможные контроллеры! (да и контроллеры в принципе)...
Чуть расширим код (очень грубый пример):
class HomeController {
public function index (Request $request){
$this->getUser($request->get('password'));
}
public function getUser(DB $db, $password){
return $db->where('user_id', $password);
}
}
Как я здесь могу получить экземпляр DB в метод getUser?
Запрашивать в методе index() контейнер (хм, а как я к нему обращусь?) и получать объект DB, который надо предварительно туда закинуть?.. что-то не так...
В общем, надеюсь суть моего замешательства ясна... Разжуёте?
Спасибо!