Nette Documentation Preview

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

.[perex]
Nette DI ist eine der interessantesten Nette-Bibliotheken. Sie kann kompilierte DI-Container erzeugen und automatisch aktualisieren, die extrem schnell und erstaunlich einfach zu konfigurieren sind.

Die von einem DI-Container zu erstellenden Dienste werden in der Regel über Konfigurationsdateien im [NEON-Format |neon:format] definiert. Der Container, den wir im [vorigen Abschnitt |container] manuell erstellt haben, würde wie folgt geschrieben werden:

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

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

Die Notation ist wirklich kurz.

Alle Abhängigkeiten, die in den Konstruktoren der Klassen `ArticleFactory` und `UserController` deklariert sind, werden von Nette DI selbst gefunden und weitergegeben, dank des so genannten [Autowiring |autowiring], so dass nichts in der Konfigurationsdatei angegeben werden muss.
Selbst wenn sich also die Parameter ändern, müssen Sie nichts in der Konfiguration ändern. Nette wird den Container automatisch neu generieren. Sie können sich also ganz auf die Anwendungsentwicklung konzentrieren.

Wenn Sie Abhängigkeiten mit Hilfe von Settern übergeben wollen, verwenden Sie dazu den [Setup-Abschnitt |services#setup].

Nette DI generiert direkt den PHP-Code für den Container. Das Ergebnis ist also eine `.php` Datei, die Sie öffnen und studieren können. So können Sie genau sehen, wie der Container funktioniert. Sie können ihn auch in der IDE debuggen und Schritt für Schritt durchgehen. Und das Wichtigste: das generierte PHP ist extrem schnell.

Nette DI kann auch [Factory-Code |factory] auf der Grundlage der bereitgestellten Schnittstelle generieren. Anstelle der Klasse `ArticleFactory` müssen wir also nur eine Schnittstelle in der Anwendung erstellen:

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

Das vollständige Beispiel finden Sie [auf GitHub |https://github.com/nette-examples/di-example-doc].


Eigenständige Verwendung .[#toc-standalone-use]
-----------------------------------------------

Die Verwendung der Nette DI-Bibliothek in einer Anwendung ist sehr einfach. Zuerst installieren wir sie mit Composer (weil das Herunterladen von Zip-Dateien so veraltet ist):

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

Der folgende Code erzeugt eine Instanz des DI-Containers entsprechend der in der Datei `config.neon` gespeicherten Konfiguration:

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

Der Container wird nur einmal erzeugt, sein Code wird in den Cache (das Verzeichnis `__DIR__ . '/temp'` ) geschrieben und bei nachfolgenden Anfragen nur von dort gelesen.

Die Methoden `getService()` oder `getByType()` werden verwendet, um Dienste zu erstellen und abzurufen. So erstellen wir das Objekt `UserController`:

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

Während der Entwicklung ist es nützlich, den Auto-Refresh-Modus zu aktivieren, bei dem der Container automatisch neu generiert wird, wenn eine Klasse oder eine Konfigurationsdatei geändert wird. Geben Sie einfach `true` als zweites Argument im `ContainerLoader` Konstruktor an.

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


Verwendung mit dem Nette Framework .[#toc-using-it-with-the-nette-framework]
----------------------------------------------------------------------------

Wie wir gezeigt haben, ist die Verwendung von Nette DI nicht auf Anwendungen beschränkt, die im Nette Framework geschrieben wurden. Sie können es überall mit nur 3 Zeilen Code einsetzen.
Wenn Sie jedoch Anwendungen im Nette Framework entwickeln, wird die Konfiguration und Erstellung des Containers von [Bootstrap |application:bootstrap#toc-di-container-configuration] übernommen.

Nette DI Container

Nette DI ist eine der interessantesten Nette-Bibliotheken. Sie kann kompilierte DI-Container erzeugen und automatisch aktualisieren, die extrem schnell und erstaunlich einfach zu konfigurieren sind.

Die von einem DI-Container zu erstellenden Dienste werden in der Regel über Konfigurationsdateien im NEON-Format definiert. Der Container, den wir im vorigen Abschnitt manuell erstellt haben, würde wie folgt geschrieben werden:

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

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

Die Notation ist wirklich kurz.

Alle Abhängigkeiten, die in den Konstruktoren der Klassen ArticleFactory und UserController deklariert sind, werden von Nette DI selbst gefunden und weitergegeben, dank des so genannten Autowiring, so dass nichts in der Konfigurationsdatei angegeben werden muss. Selbst wenn sich also die Parameter ändern, müssen Sie nichts in der Konfiguration ändern. Nette wird den Container automatisch neu generieren. Sie können sich also ganz auf die Anwendungsentwicklung konzentrieren.

Wenn Sie Abhängigkeiten mit Hilfe von Settern übergeben wollen, verwenden Sie dazu den Setup-Abschnitt.

Nette DI generiert direkt den PHP-Code für den Container. Das Ergebnis ist also eine .php Datei, die Sie öffnen und studieren können. So können Sie genau sehen, wie der Container funktioniert. Sie können ihn auch in der IDE debuggen und Schritt für Schritt durchgehen. Und das Wichtigste: das generierte PHP ist extrem schnell.

Nette DI kann auch Factory-Code auf der Grundlage der bereitgestellten Schnittstelle generieren. Anstelle der Klasse ArticleFactory müssen wir also nur eine Schnittstelle in der Anwendung erstellen:

interface ArticleFactory
{
	function create(): Article;
}

Das vollständige Beispiel finden Sie auf GitHub.

Eigenständige Verwendung

Die Verwendung der Nette DI-Bibliothek in einer Anwendung ist sehr einfach. Zuerst installieren wir sie mit Composer (weil das Herunterladen von Zip-Dateien so veraltet ist):

composer require nette/di

Der folgende Code erzeugt eine Instanz des DI-Containers entsprechend der in der Datei config.neon gespeicherten Konfiguration:

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

Der Container wird nur einmal erzeugt, sein Code wird in den Cache (das Verzeichnis __DIR__ . '/temp' ) geschrieben und bei nachfolgenden Anfragen nur von dort gelesen.

Die Methoden getService() oder getByType() werden verwendet, um Dienste zu erstellen und abzurufen. So erstellen wir das Objekt UserController:

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

Während der Entwicklung ist es nützlich, den Auto-Refresh-Modus zu aktivieren, bei dem der Container automatisch neu generiert wird, wenn eine Klasse oder eine Konfigurationsdatei geändert wird. Geben Sie einfach true als zweites Argument im ContainerLoader Konstruktor an.

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

Verwendung mit dem Nette Framework

Wie wir gezeigt haben, ist die Verwendung von Nette DI nicht auf Anwendungen beschränkt, die im Nette Framework geschrieben wurden. Sie können es überall mit nur 3 Zeilen Code einsetzen. Wenn Sie jedoch Anwendungen im Nette Framework entwickeln, wird die Konfiguration und Erstellung des Containers von Bootstrap übernommen.