Nette Documentation Preview

syntax
Nette DI-контейнер
******************

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

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

```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 |services#Setup] у визначення сервісу.

Nette DI буде фактично генерувати PHP-код для контейнера. Тому він надзвичайно швидкий, програміст точно знає, що він робить, і навіть може переступати через нього. Для великих додатків контейнер може складатися з десятків тисяч рядків, і підтримувати щось подібне вручну, імовірно, вже неможливо.

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

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

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


Використання без фреймворка .[#toc-standalone-use]
--------------------------------------------------

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

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

Ми збережемо наведену вище конфігурацію у файлі `config.neon` і створимо контейнер, використовуючи клас `Nette\DI\ContainerLoader`:

```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
$database = $container->getByType(UserController::class);
$database->query('...');
```

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

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


Використання з Nette Framework .[#toc-using-it-with-the-nette-framework]
------------------------------------------------------------------------

Як ми показали, використання Nette DI не обмежується додатками, написаними на Nette Framework, ви можете розгорнути його де завгодно, використовуючи всього 3 рядки коду.
Якщо ви розробляєте додатки в Nette, конфігурування і створення контейнера здійснюється за допомогою класу [Bootstrap |application:bootstrap#toc-di-container-configuration].

Nette DI-контейнер

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

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

Якщо ви хочете передавати залежності за допомогою сетера, ми можемо додати секцію setup у визначення сервісу.

Nette DI буде фактично генерувати PHP-код для контейнера. Тому він надзвичайно швидкий, програміст точно знає, що він робить, і навіть може переступати через нього. Для великих додатків контейнер може складатися з десятків тисяч рядків, і підтримувати щось подібне вручну, імовірно, вже неможливо.

Nette DI також може генерувати код фабрики на основі інтерфейсу. Таким чином, замість класу ArticleFactory вам потрібно буде просто створити інтерфейс:

interface ArticleFactory
{
	function create(): Article;
}

Ви можете знайти повний приклад на GitHub.

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

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

composer require nette/di

Ми збережемо наведену вище конфігурацію у файлі config.neon і створимо контейнер, використовуючи клас Nette\DI\ContainerLoader:

$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('...');

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

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

Використання з Nette Framework

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