Настройка DI-контейнера
Обзор вариантов конфигурации контейнера Nette DI.
Конфигурационный файл
Контейнером Nette DI легко управлять с помощью конфигурационных файлов. Обычно они записываются в формате NEON format. Мы рекомендуем использовать редактирования таких файлов редакторы с поддержкой этого формата.
decorator: Decorator
di: DI Container
extensions: Install additional DI extensions
includes: Including files
parameters: Parameters
search: Automatic service registration
services: Services
Чтобы записать строку, содержащую символ %
, вы должны
экранировать его удвоением до %%
.
Параметры
Можно задать параметры, которые затем могут быть использованы в качестве части определения сервиса. Это может помочь разделить значения, которые вы хотите изменять более регулярно:
В любом конфигурационном файле можно ссылаться на параметр foo
через %foo%
в другом месте. Они также могут использоваться внутри
строк, таких как '%wwwDir%/images'
.
Параметры не должны быть только строками, они могут быть также значениями массива:
Можно ссылаться на отдельный ключ так: %mailer.user%
.
Если вам нужно получить значение любого параметра в вашем коде, например, в классе, то передайте его этому классу. Например, в конструкторе. Не существует глобального объекта конфигурации, который мог бы запрашивать значения параметров. Это противоречит принципу внедрения зависимостей.
Сервисы
См. отдельную главу.
Декоратор
Как массово редактировать все сервисы определенного типа? Нужно вызвать определенный метод для всех презентеров, наследующих от определенного общего предка? Вот откуда берется декоратор:
Декоратор также можно использовать для установки тегов или включения режима внедрения.
DI
Технические настройки контейнера DI:
Ленивые услуги
Установка lazy: true
позволяет ленивое (отложенное) создание
сервисов. Это означает, что сервисы создаются не при запросе из
DI-контейнера, а только при первом использовании. Это может ускорить
запуск приложения и уменьшить потребление памяти, поскольку создаются
только те сервисы, которые необходимы для конкретного запроса.
Для конкретного сервиса ленивое создание можно настроить.
Ленивые объекты можно использовать только для пользовательских классов, но не для внутренних классов PHP. Для работы требуется PHP 8.4 или новее.
Экспорт метаданных
Класс контейнера DI также содержит множество метаданных. Вы можете уменьшить его, сократив экспорт метаданных.
Если вы не используете массив $container->getParameters()
, можно
отключить экспорт параметров. Кроме того, вы можете экспортировать
только те теги, через которые вы получаете сервисы, используя метод
$container->findByTag(...)
. Если вы не вызываете этот метод вовсе, можно
полностью отключить экспорт тегов, указав значение false
.
Вы можете значительно уменьшить метаданные для автоматического
подключения, указав классы, которые вы используете в качестве
параметра в методе $container->getByType()
. И снова, если вы не вызывайте
этот метод вовсе (или только в bootstrap для
получения Nette\Application\Application
), можно полностью отключить экспорт,
указав значение false
.
Расширения
Регистрация других расширений DI. Таким образом, мы добавляем,
например, DI расширение Dibi\Bridges\Nette\DibiExtension22
под именем
dibi
:
Затем мы настраиваем его в секции, которая также называется
dibi
:
Вы также можете добавить класс расширения с параметрами:
Включаемые файлы
Дополнительные файлы конфигурации могут быть вставлены в секции
includes
:
Название parameters.php
не является опечаткой, конфигурация также
может быть записана в PHP-файле, который возвращает её в виде массива:
Если в конфигурационных файлах появляются элементы с одинаковыми
ключами, они будут перезаписаны или объединены в случае
с массивами. Последующий включенный файл имеет более высокий
приоритет, чем предыдущий. Файл, в котором указана секция includes
,
имеет более высокий приоритет, чем файлы, включенные в него.
Поиск
Автоматическое добавление сервисов в контейнер DI делает работу чрезвычайно приятной. Nette автоматически добавляет презентеры в контейнер, но вы можете легко добавить любые другие классы.
Просто укажите, в каких каталогах (и подкаталогах) следует искать классы:
Обычно, однако, мы не хотим добавлять все классы и интерфейсы, поэтому мы можем отфильтровать их:
Или мы можем выбрать классы, которые наследуют или реализуют хотя бы один из следующих классов:
Вы также можете определить негативные правила, т. е. маски имён классов или предков, и если они соответствуют требованиям, сервис не будет добавлен в контейнер DI:
Для дополнительных сервисов можно определить теги:
Объединение
Если элементы с одинаковыми ключами появляются в нескольких конфигурационных файлах, они будут перезаписаны или объединены в случае массивов. Более поздний включенный файл имеет более высокий приоритет.
config1.neon | config2.neon | result |
---|---|---|
Чтобы предотвратить объединение определенного массива, используйте восклицательный знак сразу после имени массива:
config1.neon | config2.neon | result |
---|---|---|