Налаштування DI-контейнера

Огляд варіантів конфігурації контейнера Nette DI.

Конфігураційний файл

Контейнером Nette DI легко керувати за допомогою конфігураційних файлів. Зазвичай вони записуються у форматі NEON format. Ми рекомендуємо використовувати для редагування таких файлів редактори з підтримкою цього формату.

 decorator: 	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: ...        # (bool) за замовчуванням true

	# типи параметрів, які не потрібно монтувати автоматично
	excluded: ...        # (string[])

	# клас, від якого успадковується контейнер DI
	parentClass: ...     # (string) за замовчуванням Nette\DI\Container

Експорт метаданих

Клас контейнера DI також містить безліч метаданих. Ви можете зменшити його, скоротивши експорт метаданих.

di:
	export:
		# експортувати параметри
		parameters: false # (bool) за замовчуванням true

		# експортувати теги
		tags:             # (string[]|bool) за замовчуванням усі
			- event.subscriber

		# експортувати дані для автоматичного підключення
		types:            # (string[]|bool) за замовчуванням усі
			- 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 автоматично додає презентери в контейнер, але ви можете легко додати будь-які інші класи.

Просто вкажіть, у яких каталогах (і підкаталогах) слід шукати класи:

search:
	-	in: %appDir%/Forms
	-	in: %appDir%/Model

Зазвичай, однак, ми не хочемо додавати всі класи та інтерфейси, тому ми можемо відфільтрувати їх:

search:
	-	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 результат
items:
	- 1
	- 2
items:
	- 3
items:
	- 1
	- 2
	- 3

Щоб запобігти об'єднанню певного масиву, використовуйте знак оклику відразу після імені масиву:

config1.neon config2.neon result
items:
	- 1
	- 2
items!:
	- 3
items:
	- 3
версію: 3.x