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.