Konfiguration des DI-Containers
Übersicht über die Konfigurationsoptionen für den Nette DI Container.
Konfigurationsdatei
Der Nette DI Container lässt sich leicht über Konfigurationsdateien steuern. Diese werden normalerweise im NEON-Format geschrieben. Zur Bearbeitung empfehlen wir Editoren mit Unterstützung für dieses Format.
decorator: Decorator
di: DI-Container
extensions: Installation weiterer DI-Erweiterungen
includes: Einbinden von Dateien
parameters: Parameter
search: Automatische Registrierung von Diensten
services: Dienste
Um eine Zeichenkette zu schreiben, die das Zeichen %
enthält, müssen Sie es durch Verdoppelung auf
%%
escapen.
Parameter
In der Konfiguration können Sie Parameter definieren, die dann als Teil der Dienstdefinitionen verwendet werden können. Dadurch können Sie die Konfiguration übersichtlicher gestalten oder Werte vereinheitlichen und ausgliedern, die sich ändern werden.
parameters:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: secret
Auf den Parameter dsn
verweisen wir überall in der Konfiguration mit der Schreibweise %dsn%
.
Parameter können auch innerhalb von Zeichenketten wie '%wwwDir%/images'
verwendet werden.
Parameter müssen nicht nur Zeichenketten oder Zahlen sein, sie können auch Arrays enthalten:
parameters:
mailer:
host: smtp.example.com
secure: ssl
user: franta@gmail.com
languages: [cs, en, de]
Auf einen bestimmten Schlüssel verweisen wir als %mailer.user%
.
Wenn Sie in Ihrem Code, beispielsweise in einer Klasse, den Wert eines Parameters ermitteln müssen, übergeben Sie ihn an diese Klasse. Zum Beispiel im Konstruktor. Es gibt kein globales Objekt, das die Konfiguration repräsentiert, bei dem Klassen Parameterwerte abfragen könnten. Das würde gegen das Prinzip der Dependency Injection verstoßen.
Dienste
Siehe separates Kapitel.
Decorator
Wie kann man alle Dienste eines bestimmten Typs massenhaft ändern? Zum Beispiel eine bestimmte Methode bei allen Presentern aufrufen, die von einem bestimmten gemeinsamen Vorfahren erben? Dafür gibt es den Decorator.
decorator:
# für alle Dienste, die Instanzen dieser Klasse oder Schnittstelle sind
App\Presentation\BasePresenter:
setup:
- setProjectId(10) # rufe diese Methode auf
- $absoluteUrls = true # und setze die Variable
Der Decorator kann auch verwendet werden, um Tags zu setzen oder den inject-Modus zu aktivieren.
decorator:
InjectableInterface:
tags: [mytag: 1]
inject: true
DI
Technische Einstellungen des DI-Containers.
di:
# DIC in der Tracy Bar anzeigen?
debugger: ... # (bool) Standard ist true
# Parametertypen, die niemals autowired werden sollen
excluded: ... # (string[])
# lazy Erstellung von Diensten erlauben?
lazy: ... # (bool) Standard ist false
# Klasse, von der der DI-Container erbt
parentClass: ... # (string) Standard ist Nette\DI\Container
Lazy Dienste
Die Einstellung lazy: true
aktiviert die lazy (verzögerte) Erstellung von Diensten. Das bedeutet, dass Dienste
nicht tatsächlich erstellt werden, wenn wir sie vom DI-Container anfordern, sondern erst im Moment ihrer ersten Verwendung. Dies
kann den Start der Anwendung beschleunigen und den Speicherbedarf reduzieren, da nur die Dienste erstellt werden, die im
jeweiligen Request tatsächlich benötigt werden.
Für einen bestimmten Dienst kann die lazy Erstellung geändert werden.
Lazy Objekte können nur für benutzerdefinierte Klassen verwendet werden, nicht für interne PHP-Klassen. Erfordert PHP 8.4 oder neuer.
Export von Metadaten
Die DI-Container-Klasse enthält auch viele Metadaten. Sie können sie verkleinern, indem Sie den Export von Metadaten reduzieren.
di:
export:
# Parameter exportieren?
parameters: false # (bool) Standard ist true
# Tags exportieren und welche?
tags: # (string[]|bool) Standard sind alle
- event.subscriber
# Daten für Autowiring exportieren und welche?
types: # (string[]|bool) Standard sind alle
- Nette\Database\Connection
- Symfony\Component\Console\Application
Wenn Sie das Array $container->getParameters()
nicht verwenden, können Sie den Parameter-Export deaktivieren.
Weiterhin können Sie nur die Tags exportieren, über die Sie Dienste mit der Methode $container->findByTag(...)
abrufen. Wenn Sie die Methode überhaupt nicht aufrufen, können Sie den Tag-Export mit false
vollständig
deaktivieren.
Sie können die Metadaten für Autowiring erheblich
reduzieren, indem Sie die Klassen angeben, die Sie als Parameter der Methode $container->getByType()
verwenden.
Und wiederum, wenn Sie die Methode überhaupt nicht aufrufen (bzw. nur im Bootstrap, um Nette\Application\Application
zu erhalten),
können Sie den Export mit false
vollständig deaktivieren.
Erweiterungen
Registrierung weiterer DI-Erweiterungen. Auf diese Weise fügen wir z. B. die DI-Erweiterung
Dibi\Bridges\Nette\DibiExtension22
unter dem Namen dibi
hinzu
extensions:
dibi: Dibi\Bridges\Nette\DibiExtension22
Anschließend konfigurieren wir sie im Abschnitt dibi
:
dibi:
host: localhost
Als Erweiterung kann auch eine Klasse hinzugefügt werden, die Parameter hat:
extensions:
application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, %appDir%, %tempDir%/cache)
Dateien einbinden
Weitere Konfigurationsdateien können wir im Abschnitt includes
einfügen:
includes:
- parameters.php
- services.neon
- presenters.neon
Der Name parameters.php
ist kein Tippfehler, die Konfiguration kann auch in einer PHP-Datei geschrieben werden,
die sie als Array zurückgibt:
<?php
return [
'database' => [
'main' => [
'dsn' => 'sqlite::memory:',
],
],
];
Wenn in Konfigurationsdateien Elemente mit denselben Schlüsseln erscheinen, werden sie überschrieben oder im Falle von Arrays zusammengeführt. Eine später eingebundene Datei hat eine höhere Priorität als die
vorherige. Die Datei, in der der Abschnitt includes
aufgeführt ist, hat eine höhere Priorität als die darin
eingebundenen Dateien.
Suche
Das automatische Hinzufügen von Diensten zum DI-Container macht die Arbeit äußerst angenehm. Nette fügt Presenter automatisch zum Container hinzu, aber es können auch problemlos beliebige andere Klassen hinzugefügt werden.
Es genügt anzugeben, in welchen Verzeichnissen (und Unterverzeichnissen) nach Klassen gesucht werden soll:
search:
- in: %appDir%/Forms
- in: %appDir%/Model
Normalerweise möchten wir jedoch nicht alle Klassen und Schnittstellen hinzufügen, daher können wir sie filtern:
search:
- in: %appDir%/Forms
# Filtern nach Dateiname (string|string[])
files:
- *Factory.php
# Filtern nach Klassenname (string|string[])
classes:
- *Factory
Oder wir können Klassen auswählen, die mindestens eine der angegebenen Klassen erben oder implementieren:
search:
- in: %appDir%
extends:
- App\*Form
implements:
- App\*FormInterface
Es können auch Ausschlussregeln definiert werden, d. h. Masken für Klassennamen oder erbende Vorfahren, bei deren Übereinstimmung der Dienst nicht zum DI-Container hinzugefügt wird:
search:
- in: %appDir%
exclude:
files: ...
classes: ...
extends: ...
implements: ...
Für alle Dienste können Tags gesetzt werden:
search:
- in: %appDir%
tags: ...
Zusammenführen
Wenn in mehreren Konfigurationsdateien Elemente mit denselben Schlüsseln erscheinen, werden sie überschrieben oder im Falle von Arrays zusammengeführt. Eine später eingebundene Datei hat eine höhere Priorität als die vorherige.
config1.neon | config2.neon | Ergebnis |
---|---|---|
|
|
|
Bei Arrays kann das Zusammenführen durch Angabe eines Ausrufezeichens nach dem Schlüsselnamen verhindert werden:
config1.neon | config2.neon | Ergebnis |
---|---|---|
|
|
|