Nette DI контейнер

Nette DI е една от най-интересните библиотеки на Nette. Тя може да генерира и автоматично да актуализира компилирани DI контейнери, които са изключително бързи и невероятно лесни за конфигуриране.

Формата на сървисите, които DI контейнерът трябва да създава, обикновено дефинираме с помощта на конфигурационни файлове във формат NEON. Контейнерът, който ръчно създадохме в предишната глава, би се записал така:

parameters:
	db:
		dsn: 'mysql:'
		user: root
		password: '***'

services:
	- Nette\Database\Connection(%db.dsn%, %db.user%, %db.password%)
	- ArticleFactory
	- UserController

Записът е наистина кратък.

Всички зависимости, декларирани в конструкторите на класовете ArticleFactory и UserController, Nette DI само открива и предава благодарение на т.нар. autowiring, затова в конфигурационния файл не е необходимо да се посочва нищо. Така че дори ако параметрите се променят, не е необходимо да променяте нищо в конфигурацията. Nette контейнерът автоматично ще се прегенерира. Вие можете да се съсредоточите изцяло върху разработката на приложението.

Ако искаме да предаваме зависимости чрез сетъри, използваме за това секцията setup.

Nette DI генерира директно PHP код на контейнера. Резултатът е файл .php, който можете да отворите и изучавате. Благодарение на това виждате точно как работи контейнерът. Можете също да го дебъгвате в IDE и да го проследявате стъпка по стъпка. И най-важното: генерираният PHP е изключително бърз.

Nette DI може също да генерира код на фабрики въз основа на предоставен интерфейс. Затова вместо клас ArticleFactory ще ни е достатъчно да създадем в приложението само интерфейс:

interface ArticleFactory
{
	function create(): Article;
}

Целият пример можете да намерите в GitHub.

Самостоятелна употреба

Внедряването на библиотеката Nette DI в приложение е много лесно. Първо я инсталираме с Composer (защото изтеглянето на zip файлове е тааака остаряло):

composer require nette/di

Следващият код създава инстанция на DI контейнер според конфигурацията, съхранена във файла config.neon:

$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function ($compiler) {
	$compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;

Контейнерът се генерира само веднъж, неговият код се записва в кеша (директория __DIR__ . '/temp') и при следващи заявки се зарежда само оттам.

За създаване и получаване на сървиси служат методите getService() или getByType(). Така създаваме обект UserController:

$database = $container->getByType(UserController::class);
$database->query('...');

По време на разработка е полезно да се активира режимът на автоматично опресняване, при който контейнерът автоматично се прегенерира, ако настъпи промяна в някой клас или конфигурационен файл. Достатъчно е в конструктора на ContainerLoader да се посочи като втори аргумент true.

$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true);

Използване с Nette Framework

Както показахме, използването на Nette DI не е ограничено до приложения, написани в Nette Framework, можете да го внедрите навсякъде само с 3 реда код. Ако обаче разработвате приложения в Nette Framework, конфигурацията и създаването на контейнера се управляват от Bootstrap.

версия: 3.x