Създаване на контейнер DI
Преглед на опциите за конфигуриране на контейнера Nette DI.
Конфигурационен файл
Контейнерът Nette DI се управлява лесно с помощта на конфигурационни файлове. Обикновено те са записани във формат NEON. Препоръчваме ви да използвате редактори, които поддържат този формат, когато редактирате такива файлове.
decorator: Декоратор
di: DI Container
extensions: Инсталиране на допълнителни разширения на DI
includes: Включва файлове
parameters: Параметри
search: Автоматична регистрация на услуги
services: Услуги
Записване на низ, съдържащ символа %
, вы должны
экранировать его удвоением до %%
.
Параметри
Можете да зададете параметри, които след това да бъдат използвани като част от дефиницията на услугата. Това може да ви помогне да отделите стойностите, които искате да променяте по-редовно:
parameters:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: secret
Във всеки конфигурационен файл можете да се позовавате на параметъра
foo
чрез %foo%
на друго място. Те могат да се използват и в
рамките на редове като '%wwwDir%/images'
.
Не е задължително параметрите да бъдат само низове, те могат да бъдат и стойности на масиви:
parameters:
mailer:
host: smtp.example.com
secure: ssl
user: franta@gmail.com
languages: [cs, en, de]
Можете да се обърнете към отделен ключ по следния начин:
%mailer.user%
.
Ако трябва да получите стойността на някой параметър в кода си, например в клас, предайте го на този клас. Например, в конструктора. Няма обект на глобалната конфигурация, който да може да изисква стойности на параметрите. Това противоречи на принципа на прилагане на зависимостите.
Услуги
Вижте отделна глава.
Декоратор
Как да редактирам масово всички услуги от определен тип? Трябва ли да извикате определен метод за всички презентатори, наследени от определен общ предшественик? Оттук идва декораторът:
decorator:
# За всички услуги, които са екземпляри на този клас или интерфейс
App\UI\BasePresenter:
setup:
- setProjectId(10) # извикване на този метод
- $absoluteUrls = true # и задаване на променлива
Декораторът може да се използва и за задаване на тагове или за активиране на режима на вграждане.
decorator:
InjectableInterface:
tags: [mytag: 1]
inject: true
DI
Технически настройки за контейнера DI:
di:
# показване на DIC в Tracy debugger?
debugger: ... # (bool) по подразбиране е true
# типове параметри, които не е необходимо да се монтират автоматично
excluded: ... # (string[])
# клас, от който е наследен контейнерът DI
parentClass: ... # (string) по подразбиране Nette\DI\Container
Експорт на метаданни
Контейнерният клас DI съдържа и много метаданни. Можете да го намалите, като намалите експортирането на метаданни.
di:
export:
# параметри за износ
parameters: false # (bool) по подразбиране е true
# експортни тагове
tags: # (string[]|bool) по подразбиране е all
- event.subscriber
# експортиране на данни за автоматично свързване
types: # (string[]|bool) по подразбиране е all
- Nette\Database\Connection
- Symfony\Component\Console\Application
Ако не използвате масива $container->getParameters()
, можете да
деактивирате експортирането на параметри. Като алтернатива можете да
експортирате само тези тагове, чрез които получавате услуги, като
използвате метода $container->findByTag(...)
. Ако изобщо не извиквате този
метод, можете да деактивирате напълно експортирането на тагове, като
посочите false
.
Можете значително да намалите метаданните за автоматичното
свързване, като посочите класовете, които използвате, като параметър в
метода $container->getByType()
. Отново, ако изобщо не извиквате този
метод (или само в bootstrap, за да получите
Nette\Application\Application
), можете да деактивирате износа напълно, като
посочите стойността false
.
Удължения
Регистрация на други разширения на DI. Така например добавяме
разширението DI Dibi\Bridges\Nette\DibiExtension22
под името dibi
:
extensions:
dibi: Dibi\Bridges\Nette\DibiExtension22
След това го създаваме в раздела, наречен също dibi
:
dibi:
host: localhost
Можете също така да добавите клас за разширение с параметри:
extensions:
application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, %appDir%, %tempDir%/cache)
Включване на файлове
Допълнителни конфигурационни файлове могат да бъдат вмъкнати в
разделите includes
:
includes:
- parameters.php
- services.neon
- presenters.neon
Името parameters.php
не е печатна грешка, конфигурацията може да бъде
записана и в PHP файл, който я връща като масив:
<?php
return [
'database' => [
'main' => [
'dsn' => 'sqlite::memory:',
],
],
];
Ако в конфигурационните файлове се появят елементи със същите
ключове, те ще бъдат презаписани или обединени в случай
на масиви. Следващият включен файл е с по-висок приоритет от предишния.
Файл, в който е посочен разделът includes
, има по-висок приоритет от
включените в него файлове.
Търсене за
Автоматичното добавяне на услуги към контейнера DI го прави изключително удобен за работа. Nette автоматично добавя водещи към контейнера, но можете лесно да добавите и други класове.
Просто посочете в кои директории (и поддиректории) трябва да се търсят класовете:
търсене:
- in: %appDir%/Forms
- in: %appDir%/Model
Обикновено обаче не искаме да добавяме всички класове и интерфейси, затова можем да ги филтрираме:
търсене:
- in: %appDir%/Forms
# филтриране по име на файл (string|string[])
files:
- *Factory.php
# филтриране по име на клас (string|string[])
classes:
- *Factory
Или можем да изберем класове, които наследяват или имплементират поне един от следните класове:
search:
- in: %appDir%
extends:
- App\*Form
implements:
- App\*FormInterface
Можете също така да дефинирате отрицателни правила, т.е. маски за имена на класове или предци, и ако те отговарят на изискванията, услугата няма да бъде добавена към контейнера DI:
search:
- in: %appDir%
exclude:
файлове: ...
classes: ...
extends: ...
implements: ...
Могат да се дефинират етикети за допълнителни услуги:
search:
- in: %appDir%
tags: ...
Асоциация
Ако елементи с еднакви ключове се появят в няколко конфигурационни файла, те ще бъдат презаписани или обединени в случай на масиви. По-късно включеният файл е с по-висок приоритет.
config1.neon | config2.neon | резултат |
---|---|---|
|
|
|
За да предотвратите присъединяването на определен масив, използвайте възклицателен знак непосредствено след името на масива:
config1.neon | config2.neon | резултат |
---|---|---|
|
|
|