Печать
Родительская категория: Yii2
Категория: Полное руководство по Yii 2.0

Рейтинг:  0 / 5

Звезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активна
 

Более сложное практическое применение

Более сложное практическое применение

Допустим, мы работаем над API и у нас есть:



Возможно настроить несколько компонентов сразу передав массив конфигурации в метод [[yii\di\Container::setDefinitions()|setDefinitions()]] или [[yii\di\Container::setSingletons()|setSingletons()]]. Внутри метода фреймворк обойдёт массив конфигурации и вызовет для каждого элемента [[yii\di\Container::set()|set()]] или [[yii\di\Container::setSingleton()|setSingleton()]] соответственно.

Формат массива конфигурации следующий:

Для примера, давайте настроим наш контейнер:

$container->setDefinitions([
    'yii\web\Request' => 'app\components\Request',
    'yii\web\Response' => [
        'class' => 'app\components\Response',
        'format' => 'json'
    ],
    'app\storage\DocumentsReader' => function () {
        $fs = new app\storage\FileStorage('/var/tempfiles');
        return new app\storage\DocumentsReader($fs);
    }
]);

$reader = $container->get('app\storage\DocumentsReader); 
// Создаст объект DocumentReader со всеми зависимостями

Tip: Начиная с версии 2.0.11 контейнер может быть настроен в декларативном стиле через конфигурацию приложения. Как это сделать ищите в подразделе Конфигурация приложения раздела Конфигурации.

Вроде всё работает, но если нам необходимо создать экземпляр класса DocumentWriter, придётся скопировать код, создающий экземплярFileStorage, что, очевидно, не является оптимальным.

Как описано в подразделе Разрешение зависимостей, [[yii\di\Container::set()|set()]] и [[yii\di\Container::setSingleton()|setSingleton()]] могут опционально принимать третьим аргументов параметры для конструктора. Формат таков:

Исправим наш пример:

$container->setDefinitions([
    'tempFileStorage' => [ // для удобства мы задали псевдоним
        ['class' => 'app\storage\FileStorage'],
        ['/var/tempfiles']
    ],
    'app\storage\DocumentsReader' => [
        ['class' => 'app\storage\DocumentsReader'],
        [Instance::of('tempFileStorage')]
    ],
    'app\storage\DocumentsWriter' => [
        ['class' => 'app\storage\DocumentsWriter'],
        [Instance::of('tempFileStorage')]
    ]
]);

$reader = $container->get('app\storage\DocumentsReader); 
// Код будет работать ровно так же, как и в предыдущем примере.

Вы могли заметить вызов Instance::of('tempFileStorage'). Он означает, что [[yii\di\Container|Container]] наявно предоставит зависимость, зарегистрированную с именем tempFileStorage и передаст её первым аргументом в конструктор app\storage\DocumentsWriter.

Note: Методы [[yii\di\Container::setDefinitions()|setDefinitions()]] и [[yii\di\Container::setSingletons()|setSingletons()]] доступны с версии 2.0.11.

Ещё один шаг по оптимизации конфигурации — регистрировать некоторые зависимости как синглтоны. Зависимость, регистрируемая через метод [[yii\di\Container::set()|set()]] будет созаваться каждый раз при обращении к ней. Некоторые классы не меняют своего состояния на протяжении всей работы приложения, поэтому могут быть зарегистрированы как синглтоны. Это увеличит производительность приложения.

Хорошим примером может быть класс app\storage\FileStorage, который выполняет некие операции над файловой системой через простой API: $fs->read(), $fs->write(). Обе операции не меняют внутреннее состояние класса, поэтому мы можем создать класс один раз и далее использовать его.

$container->setSingletons([
    'tempFileStorage' => [
        ['class' => 'app\storage\FileStorage'],
        ['/var/tempfiles']
    ],
]);

$container->setDefinitions([
    'app\storage\DocumentsReader' => [
        ['class' => 'app\storage\DocumentsReader'],
        [Instance::of('tempFileStorage')]
    ],
    'app\storage\DocumentsWriter' => [
        ['class' => 'app\storage\DocumentsWriter'],
        [Instance::of('tempFileStorage')]
    ]
]);

$reader = $container->get('app\storage\DocumentsReader');

Заберите ссылку на статью к себе, чтобы потом легко её найти ;)

Выберите, то, чем пользуетесь чаще всего:

Спасибо за внимание, оставайтесь на связи! Ниже ссылка на форум и обсуждение ; )

Войдите, чтобы комментировать


Обсудить эту статью

INFO: Вы отправляете сообщение как 'Гость'