Создание расширений для Nette DI
Создание контейнера DI в дополнение к файлам конфигурации
также влияет на так называемые расширения. Мы активируем их в файле
конфигурации в секции extensions
.
Так мы добавляем расширение, представленное классом BlogExtension
с
именем blog
:
Каждое расширение компилятора наследует от Nette\DI\CompilerExtension и может реализовать следующие методы, которые вызываются при компиляции DI:
- getConfigSchema()
- loadConfiguration()
- beforeCompile()
- afterCompile()
getConfigSchema()
Этот метод вызывается первым. Он определяет схему, используемую для проверки параметров конфигурации.
Расширения настроены в секции, имя которой совпадает с именем, под
которым добавлено расширение, например, blog
.
Мы определим схему, описывающую все параметры конфигурации, включая их типы, принятые значения и, возможно, значения по умолчанию:
См. Schema для получения информации. Кроме того,
можно указать, какие опции могут быть динамическими с помощью
dynamic()', например `Expect::int()->dynamic()
.
Мы получаем доступ к конфигурации через $this->config
, который
является объектом stdClass
:
loadConfiguration()
Этот метод используется для добавления сервисов в контейнер. Это делается с помощью Nette\DI\ContainerBuilder:
Конвенция предусматривает префиксирование сервисов, добавленных
расширением с его именем, чтобы не возникали конфликтов имен. Это
делается с помощью
prefix()', так что если расширение называется 'blog', то служба будет называться `blog.articles
.
Если нам нужно переименовать сервис, мы можем создать псевдоним с его
первоначальным именем, чтобы сохранить обратную совместимость. Точно
так же делает Nette для routing.router
, который также доступен под ранним
названием router
.
Получение сервисов из файла
Мы можем создавать сервисы с помощью API ContainerBuilder, но также можем
добавить их через знакомый файл конфигурации NEON и его секцию
services
. Префикс @extension
представляет текущее расширение.
Мы добавим сервисы таким образом:
beforeCompile()
Метод вызывается, когда контейнер содержит все сервисы, добавленные
отдельными расширениями в методах loadConfiguration
, а также файлы
конфигурации пользователя. На этом этапе сборки мы можем изменять
определения сервиса или добавлять ссылки между ними. Для поиска
сервисов по тегам можно использовать метод findByTag()
, или метод
findByType()
для поиска по классу или интерфейсу.
afterCompile()
На этой стадии класс контейнера уже генерируется как объект ClassType, содержит все методы, которые создаются сервисом, и готов к кэшированию как файл PHP. В данный момент мы можем редактировать код класса.
$initialization
Configurator вызывается кодом инициализации после создания контейнера, который
создается путем записи в объект $this->initialization
с помощью метода addBody().
Мы покажем пример того, как запустить сессию или сервисы, которые
имеют тег run
с помощью кода инициализации: