Answer the question
In order to leave comments, you need to log in
How to properly organize dependency injection in Yii2?
Described the dependencies in the configuration file config/di.php .
<?php
/**
* @var $container \yii\di\Container
*/
$container = Yii::$container;
$repositories = [
# Авторизация - Роли
'common\domain\Entities\Auth\Role\Interfaces\Repository' => [
'concrete' => 'common\infrastructure\Entities\Auth\Role\Repository',
'model' => 'common\models\ActiveRecord\AuthRole',
],
# Авторизация - Роли - Назначения
'common\domain\Entities\Auth\Role\Assignment\Interfaces\Repository' => [
'concrete' => 'common\infrastructure\Entities\Auth\Role\Assignment\Repository',
'model' => 'common\models\ActiveRecord\AuthAssignment',
],
# Авторизация - Типы персон (формы собственности)
'common\domain\Entities\Auth\PersonType\Interfaces\Repository' => [
'concrete' => 'common\infrastructure\Entities\Auth\PersonType\Repository',
'model' => 'common\models\ActiveRecord\AuthPersonType',
],
# Юзер
'common\domain\Entities\User\Interfaces\Repository' => [
'concrete' => 'common\infrastructure\Entities\User\Repository',
'model' => 'common\models\User',
],
# Юзер - Профиль
'common\domain\Entities\User\Profile\Interfaces\Repository' => [
'concrete' => 'common\infrastructure\Entities\User\Profile\Repository',
'model' => 'common\models\ActiveRecord\UserProfile',
],
# Юзер - Адреса
'common\domain\Entities\User\Address\Interfaces\Repository' => [
'concrete' => 'common\infrastructure\Entities\User\Address\Repository',
'model' => 'common\models\ActiveRecord\UserAddress',
],
];
foreach ($repositories as $abstract => $realisation) {
$model = $realisation['model'];
$concrete = $realisation['concrete'];
$container->setSingletons(
[
// С абстракции (интерфейса) на реализацию
$abstract => $concrete,
// Инъекция модели в реализацию
$concrete => function () use ($concrete, $model) {
return new $concrete(new $model);
},
]
);
}
<?php
/**
* @var $container \yii\di\Container
*/
$container = Yii::$container;
$services = [
# Авторизация - Безопасность
'common\domain\Entities\Auth\Security\Interfaces\Service' => [
'concrete' => 'common\application\Auth\Security\Service',
'args' => [],
],
# Авторизация - Роли
'common\domain\Entities\Auth\Role\Interfaces\Service' => [
'concrete' => 'common\application\Auth\Role\Service',
'args' => [
'common\domain\Entities\Auth\Role\Interfaces\Repository',
'common\domain\Entities\Auth\Role\Assignment\Interfaces\Repository'
],
],
# Авторизация - Типы персон (формы собственности)
'common\domain\Entities\Auth\PersonType\Interfaces\Service' => [
'concrete' => 'common\application\Auth\PersonType\Service',
'args' => [
'common\domain\Entities\Auth\PersonType\Interfaces\Repository',
],
],
# Юзер
'common\domain\Entities\User\Interfaces\Service' => [
'concrete' => 'common\application\User\Service',
'args' => [
'common\domain\Entities\User\Interfaces\Repository',
'common\domain\Entities\Auth\Security\Interfaces\Service',
'common\domain\Entities\Auth\Role\Interfaces\Service',
'common\domain\Entities\User\Profile\Interfaces\Service'
],
],
# Юзер - Профиль
'common\domain\Entities\User\Profile\Interfaces\Service' => [
'concrete' => 'common\application\User\Profile\Service',
'args' => [
'common\domain\Entities\User\Profile\Interfaces\Repository',
],
],
# Юзер - Адреса
'common\domain\Entities\User\Address\Interfaces\Service' => [
'concrete' => 'common\application\User\Address\Service',
'args' => [
'common\domain\Entities\User\Address\Interfaces\Repository',
],
],
];
foreach ($services as $abstract => $realisation) {
$arguments = $realisation['args'] ?? null;
$concrete = $realisation['concrete'];
$container->setSingletons(
[
// С абстракции (интерфейса) на реализацию
$abstract => $concrete,
// Инъекция зависимостей в реализацию сервиса
$concrete => function () use ($container, $concrete, $arguments) {
$dependencies = array_map(
function ($item) use ($container) {
return $container->get($item);
},
$arguments
);
return new $concrete(
...$dependencies
);
},
]
);
}
Answer the question
In order to leave comments, you need to log in
You do not quite correctly understand the tasks of the dependency container and how it works. Therefore, I recommend that you read the documentation .
The essence of the container is that you configure the configurations of the components located in it, as well as the dependencies of the components from each other, and the container itself already understands how to create an object based on all this data and with all the dependencies. You essentially only wrote extra code that is implemented in the default container.
Take for example your repository object, it is enough to register it in the container like this
Yii::$container->setSingleton('common\domain\Entities\User\Profile\Interfaces\Repository', // указываем интерфейс
[ // указываем конфигурацию класса реализующего этот интерфейс
'class' => 'common\infrastructure\Entities\User\Profile\Repository'
],
[ // указываем какие данные необходимо передать в конструктор, в частности - экземпляр класса UserProfile
Instance::of('common\models\ActiveRecord\UserProfile')
]
);
Yii::$container->setSingleton('common\domain\Entities\User\Profile\Interfaces\Service',
[
'class' => 'common\application\User\Profile\Service',
],
[
Instance::of('common\domain\Entities\User\Profile\Interfaces\Repository')
],
);
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question