Създаване на контейнер 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\Presenters\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 резултат
items:
	- 1
	- 2
items:
	- 3
items:
	- 1
	- 2
	- 3

За да предотвратите присъединяването на определен масив, използвайте възклицателен знак непосредствено след името на масива:

config1.neon config2.neon резултат
items:
	- 1
	- 2
items!:
	- 3
items:
	- 3
версия: 3.x