Визначення сервісів
Конфігурація – це місце, де ми вказуємо DI контейнеру, як зібрати окремі сервіси і як з'єднати їх з іншими залежностями. Nette надає дуже чіткий та елегантний спосіб досягти цього.
Секція services
у файлі конфігурації NEON – це місце, де ми
визначаємо наші кастомні сервіси та їхні конфігурації. Давайте
розглянемо простий приклад визначення сервісу з ім'ям database
,
який представляє екземпляр класу PDO
:
Ця конфігурація призводить до наступного заводського методу в контейнері DI:
Назви сервісів дозволяють нам посилатися на них в інших частинах
конфігураційного файлу, використовуючи формат @serviceName
. Якщо
немає необхідності називати службу, ми можемо просто використовувати
маркер:
Щоб отримати сервіс з контейнера DI, ми можемо використовувати метод
getService()
з назвою сервісу як параметром або метод getByType()
з
типом сервісу:
Створення сервісу
Найчастіше ми створюємо сервіс, просто створюючи екземпляр певного класу. Наприклад:
Якщо нам потрібно розширити конфігурацію за допомогою додаткових ключів, визначення можна розгорнути на кілька рядків:
Ключ create
має псевдонім factory
, обидві версії поширені на
практиці. Однак ми рекомендуємо використовувати create
.
Аргументи конструктора або метод створення можна також записати в
ключі arguments
:
Сервіси не обов'язково створювати простим екземпляром класу; вони також можуть бути результатом виклику статичних методів або методів інших сервісів:
Зауважте, що для простоти замість ->
ми використовуємо
::
, див. засоби вираження. Ці фабричні методи
генеруються:
Контейнер DI повинен знати тип створюваного сервісу. Якщо ми створюємо сервіс за допомогою методу, який не має визначеного типу повернення, ми повинні явно вказати цей тип у конфігурації:
Аргументи
Ми передаємо аргументи конструкторам і методам у спосіб, дуже схожий на звичайний PHP:
Для кращої читабельності ми можемо перераховувати аргументи в окремих рядках. У цьому форматі використання ком не є обов'язковим:
Ви також можете назвати аргументи, що дозволить вам не турбуватися про їх порядок:
Якщо ви хочете пропустити певні аргументи і використовувати їхні значення за замовчуванням або вставити сервіс за допомогою автопідключення, використовуйте символ підкреслення:
Аргументами можуть бути сервіси, параметри та багато іншого, див. розділ Засоби вираження.
Налаштування
У розділі setup
ми визначаємо методи, які слід викликати при
створенні сервісу.
На PHP це буде виглядати так:
Крім викликів методів, ви також можете передавати значення властивостям. Додавання елемента до масиву також підтримується, але його потрібно брати в лапки, щоб уникнути конфлікту з синтаксисом NEON:
У PHP це матиме вигляд:
У налаштуванні ви також можете викликати статичні методи або методи
інших сервісів. Якщо вам потрібно передати поточний сервіс як
аргумент, використовуйте @self
:
Зауважте, що для простоти замість ->
ми використовуємо
::
, див. засоби вираження. Це генерує
наступний заводський метод:
Засоби вираження
Nette DI надає нам надзвичайно багаті можливості для вираження, що дозволяє сформулювати майже все, що завгодно. У конфігураційних файлах ми можемо використовувати параметри:
Ми також можемо створювати об'єкти, викликати методи та функції:
Звертайтеся до сервісів за назвою або за типом:
Використовуйте першокласний синтаксис викликів:
Використовуйте константи:
Виклики методів можна об'єднувати в ланцюжок, так само як і в PHP. Для
простоти, замість ->
ми використовуємо ::
:
Ці вирази можна використовувати будь-де при створенні сервісів, в аргументах, в розділі налаштувань або параметрах:
Спеціальні функції
У файлах конфігурації ви можете використовувати ці спеціальні функції:
not()
для заперечення значенняbool()
,int()
,float()
,string()
для приведення типів без втратtyped()
для створення масиву всіх сервісів заданого типуtagged()
для створення масиву всіх сервісів із заданим тегом
У порівнянні зі звичайним приведенням типів у PHP, наприклад,
(int)
, приведення типів без втрат згенерує виключення для
нечислових значень.
Функція typed()
створює масив усіх сервісів певного типу (класу
або інтерфейсу). Вона виключає сервіси з вимкненим автопідключенням.
Можна вказати декілька типів, розділених комами.
Ви також можете автоматично передати масив сервісів певного типу як аргумент за допомогою автопідключення.
Функція tagged()
створює масив усіх сервісів із зазначеним тегом.
Можна перерахувати декілька тегів, розділених комами.
Автопроводка
За допомогою ключа autowired
ви можете змінити поведінку
автопідключення для певного сервісу. Для більш детальної інформації
дивіться розділ про автопідключення.
Ліниві сервіси
Ліниве завантаження – це техніка, яка відкладає створення сервісу до моменту, коли він дійсно буде потрібен. Ви можете увімкнути ліниве створення сервісів глобально в конфігурації для всіх сервісів одразу. Для окремих сервісів цю поведінку можна перевизначити:
Коли сервіс визначено як лінивий, запит до нього з контейнера DI повертатиме спеціальний проксі-об'єкт. Цей проксі виглядає і поводиться як справжній сервіс, але справжня ініціалізація (виклик конструктора і налаштування) відбудеться лише при першому виклику будь-якого з його методів або властивостей.
Ліниве завантаження можна використовувати лише для класів, визначених користувачем, але не для внутрішніх класів PHP. Потрібна версія PHP 8.4 або новіша.
Теги
Теги використовуються для додавання додаткової інформації до послуг. Ви можете призначити послузі один або декілька тегів:
Мітки також можуть мати значення:
Щоб отримати всі сервіси з певними тегами, ви можете скористатися
функцією tagged()
:
У контейнері DI ви можете отримати назви всіх сервісів з певним тегом
за допомогою методу findByTag()
:
Режим впорскування
Використання прапора inject: true
активує передачу залежностей
через загальнодоступні змінні з анотацією inject та методами inject*( ).
За замовчуванням прапорець inject
активовано лише для
доповідачів.
Модифікації сервісу
Контейнер DI містить багато сервісів, доданих за допомогою вбудованих
або користувацьких розширень. Ви можете змінювати
визначення цих сервісів безпосередньо в конфігурації. Наприклад, ви
можете змінити клас сервісу application.application
, який умовно
називається Nette\Application\Application
, на щось інше:
Прапорець alteration
є інформативним, вказуючи на те, що ми просто
змінюємо існуючий сервіс.
Ми також можемо доповнити налаштування:
При перезаписуванні сервісу ви можете захотіти видалити оригінальні
аргументи, елементи налаштувань або теги, і саме тут у нагоді стане
reset
:
Якщо ви хочете видалити сервіс, доданий розширенням, ви можете зробити це так: