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.