Nette Documentation Preview

syntax
Nette DI Container
******************

.[perex]
Nette DI - одна з найцікавіших бібліотек Nette. Вона вміє генерувати та автоматично оновлювати скомпільовані DI-контейнери, які є надзвичайно швидкими та дивовижно легко конфігуруються.

Вигляд сервісів, які має створювати DI-контейнер, ми зазвичай визначаємо за допомогою конфігураційних файлів у [форматі NEON |neon:format]. Контейнер, який ми вручну створили в [попередньому розділі |container], записується так:

```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 |autowiring], тому в конфігураційному файлі нічого вказувати не потрібно. Тож навіть якщо параметри зміняться, вам не потрібно нічого змінювати в конфігурації. Контейнер Nette автоматично перегенерується. Ви можете зосередитися виключно на розробці застосунку.

Якщо ми хочемо передавати залежності за допомогою сеттерів, ми використовуємо для цього секцію [setup |services#Setup].

Nette DI генерує безпосередньо PHP-код контейнера. Результатом є файл `.php`, який ви можете відкрити та вивчити. Завдяки цьому ви точно бачите, як працює контейнер. Ви також можете налагоджувати його в IDE та виконувати покроково. І головне: згенерований PHP надзвичайно швидкий.

Nette DI також вміє генерувати код [фабрик |factory] на основі наданого інтерфейсу. Тому замість класу `ArticleFactory` нам достатньо буде створити в застосунку лише інтерфейс:

```php
interface ArticleFactory
{
	function create(): Article;
}
```

Повний приклад ви знайдете [на GitHub |https://github.com/nette-examples/di-example-doc].


Самостійне використання
-----------------------

Впровадження бібліотеки Nette DI в застосунок дуже просте. Спочатку встановимо її за допомогою Composer (бо завантаження zip-архівів тааак застаріло):

```shell
composer require nette/di
```

Наступний код створить екземпляр DI-контейнера відповідно до конфігурації, збереженої у файлі `config.neon`:

```php
$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`:

```php
$controller = $container->getByType(UserController::class);
$controller->someMethod();
```

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

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


Використання з фреймворком Nette
--------------------------------

Як ми показали, використання Nette DI не обмежується застосунками, написаними на Nette Framework, ви можете впровадити його де завгодно за допомогою лише 3 рядків коду. Однак, якщо ви розробляєте застосунки на Nette Framework, конфігурацією та створенням контейнера займається [Bootstrap |application:bootstrapping#Конфігурація DI-контейнера].

Nette DI Container

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:

$controller = $container->getByType(UserController::class);
$controller->someMethod();

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

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

Використання з фреймворком Nette

Як ми показали, використання Nette DI не обмежується застосунками, написаними на Nette Framework, ви можете впровадити його де завгодно за допомогою лише 3 рядків коду. Однак, якщо ви розробляєте застосунки на Nette Framework, конфігурацією та створенням контейнера займається Bootstrap.