Как использовать Di container? Только вчера познакомили с DI-контейнером и вроде документация ясная и примеров куча, но не доходит до меня.
Есть class App {

private $companyService;
public function __construct() {

$container = new Container;
$container->add('CompanyCreateService', CompanyCreateService::class)
->addArgument(CompanySqlRepository::class);
$container->add(CompanySqlRepository::class)
->addArgument(DbConnection::class)
->addArgument(Hydrator::class);
$container->add(CompanySqlRepository::class);
$container->add(DbConnection::class);
$container->add(Hydrator::class);
$container->add(AdminController::class);
$container->add('AdminController', AdminController::class)->addArgument('CompanyCreateService');
$this->companyService = $container->get('AdminController');
$this->actionIndex();
}
public function actionIndex() {
$controller = new AdminController();
}
Здесь я зарегистрировал контейнер и хочу запустить контроллер class AdminController {
public $companyService;

public function __construct(CompanyServiceInterface $companyService) {
$this->companyService = $companyService;
$this->actionCreate();
}
public function actionCreate() {
$dto = [...]
$this->companyService->createCompany($dto);
echo 'saved';
Из контроллера App я запускаю AdminController без параметров.
И получаю ошибку Fatal error: Uncaught ArgumentCountError: Too few arguments to function , что логично, так как никакой параметр я в конструктор не передаю. Но при этом данные всё равно в базу сейвятся как должны.
Вопрос1 - нужно ли всё равно передавать параметр в конструктор вызываемого контроллера или можно просто вызывать без параметров?
Вопрос2 - где вообще надо делать $container->get('что-нибудь'); ?
В самом контроллере как-то неправильно, наверное - ибо тогда всё равно зависимость. Где это делать?

21 Авг 2019 в 06:58
211 +1
1
Ответы
1

Ответ на первый вопрос: В DI контейнере регистрируются зависимости и создаются объекты с зависимостями автоматически. Поэтому вам не нужно вручную передавать параметры в конструктор контроллера. DI контейнер сам будет внедрять зависимости при создании объекта.

Ответ на второй вопрос: Обычно $container->get('что-нибудь') делается в точке входа вашего приложения, например, в файле index.php или bootstrap файлах. Там вы создаете контейнер, регистрируете все зависимости и после этого получаете объекты из контейнера для использования в дальнейшем.

Примерно так это может выглядеть:

$container = new Container;
$container->add('CompanyCreateService', CompanyCreateService::class)
->addArgument(CompanySqlRepository::class);
$container->add(CompanySqlRepository::class)
->addArgument(DbConnection::class)
->addArgument(Hydrator::class);
$container->add(DbConnection::class);
$container->add(Hydrator::class);
$container->add(AdminController::class);
$container->add('AdminController', AdminController::class)->addArgument('CompanyCreateService');
$adminController = $container->get('AdminController');

Таким образом, контейнер будет создавать все необходимые зависимости и внедрять их в объекты при их создании.

20 Апр 2024 в 13:10
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир