Nette DI Container
Nette DI ist eine der interessantesten Bibliotheken von Nette. Sie kann kompilierte DI-Container generieren und automatisch aktualisieren, die extrem schnell und erstaunlich einfach zu konfigurieren sind.
Die Form der Dienste, die der DI-Container erstellen soll, definieren wir normalerweise mithilfe von Konfigurationsdateien im NEON-Format. Der Container, den wir im vorherigen Kapitel manuell erstellt haben, würde so geschrieben werden:
parameters:
db:
dsn: 'mysql:'
user: root
password: '***'
services:
- Nette\Database\Connection(%db.dsn%, %db.user%, %db.password%)
- ArticleFactory
- UserController
Die Notation ist sehr prägnant.
Alle in den Konstruktoren der Klassen ArticleFactory
und UserController
deklarierten Abhängigkeiten
findet Nette DI selbst heraus und übergibt sie dank des sogenannten Autowiring. Daher muss in der Konfigurationsdatei nichts
angegeben werden. Selbst wenn sich die Parameter ändern, müssen Sie in der Konfiguration nichts ändern. Der Nette-Container
wird automatisch neu generiert. Sie können sich dort ganz auf die Entwicklung der Anwendung konzentrieren.
Wenn wir Abhängigkeiten über Setter übergeben möchten, verwenden wir dazu den Abschnitt setup.
Nette DI generiert direkt PHP-Code für den Container. Das Ergebnis ist also eine .php
-Datei, die Sie öffnen und
studieren können. Dadurch sehen Sie genau, wie der Container funktioniert. Sie können ihn auch in der IDE debuggen und
schrittweise durchgehen. Und vor allem: Das generierte PHP ist extrem schnell.
Nette DI kann auch Code für Fabriken basierend auf einer
bereitgestellten Schnittstelle generieren. Anstelle der Klasse ArticleFactory
reicht es uns daher aus, in der
Anwendung nur eine Schnittstelle zu erstellen:
interface ArticleFactory
{
function create(): Article;
}
Das vollständige Beispiel finden Sie auf GitHub.
Eigenständige Verwendung
Der Einsatz der Nette DI-Bibliothek in einer Anwendung ist sehr einfach. Zuerst installieren wir sie mit Composer (denn das Herunterladen von ZIP-Dateien ist sooo veraltet):
composer require nette/di
Der folgende Code erstellt eine Instanz des DI-Containers gemäß der Konfiguration, die in der Datei config.neon
gespeichert ist:
$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 generiert, sein Code wird im Cache (Verzeichnis __DIR__ . '/temp'
) gespeichert und
bei weiteren Anfragen nur noch von dort geladen.
Zum Erstellen und Abrufen von Diensten dienen die Methoden getService()
oder getByType()
. So
erstellen wir das UserController
-Objekt:
$controller = $container->getByType(UserController::class);
$controller->someMethod();
Während der Entwicklung ist es nützlich, den Auto-Refresh-Modus zu aktivieren, bei dem der Container automatisch neu
generiert wird, wenn sich eine Klasse oder Konfigurationsdatei ändert. Geben Sie einfach im Konstruktor von
ContainerLoader
als zweites Argument true
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 mit nur 3 Zeilen Code überall einsetzen. Wenn Sie jedoch Anwendungen im Nette Framework entwickeln, ist der Bootstrap für die Konfiguration und Erstellung des Containers verantwortlich.