Andex
@Andex

Объясните по внедрению зависимостей, контейнерам?

Не могу понять конструкции работы контейнера зависимостей... может кто объяснит на пальцах. а лучше примерами кода.

Играясь с ларавелем, применял такую конструкцию

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, который надо предварительно туда закинуть?.. что-то не так...

В общем, надеюсь суть моего замешательства ясна... Разжуёте?

Спасибо!
  • Вопрос задан
  • 305 просмотров
Пригласить эксперта
Ответы на вопрос 1
SerafimArts
@SerafimArts
Senior Notepad Reader
Намекаю: Pimple и Laravel - это немного разные вещи ;) Контейнер у лары самый мощный из существующих (и не только в мире php), отсюда и возможностей у него больше, включая вызов методов с автовайрингом.

По-этому реомендую брать не Pimple, а Illuminate контейнер и с ним играться, а заодно почитать: https://habrahabr.ru/post/331982/

P.S. В обычном мире смертных, что pimple, что симфонёвый, что php-di (говорят что последняя версия сильно подросла по плюшкам, но это надо проверить) - это обычный репозиторий с объектами (если утрировать, то тупой массив), максимум что они умеют - это автоматом подсовывать аргументы в конструктор.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы