Как использовать 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('что-нибудь'); ? В самом контроллере как-то неправильно, наверное - ибо тогда всё равно зависимость. Где это делать?
Ответ на первый вопрос: В DI контейнере регистрируются зависимости и создаются объекты с зависимостями автоматически. Поэтому вам не нужно вручную передавать параметры в конструктор контроллера. DI контейнер сам будет внедрять зависимости при создании объекта.
Ответ на второй вопрос: Обычно $container->get('что-нибудь') делается в точке входа вашего приложения, например, в файле index.php или bootstrap файлах. Там вы создаете контейнер, регистрируете все зависимости и после этого получаете объекты из контейнера для использования в дальнейшем.
Ответ на первый вопрос: В 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');
Таким образом, контейнер будет создавать все необходимые зависимости и внедрять их в объекты при их создании.