Nette Documentation Preview

syntax
Konfiguration des DI-Containers
*******************************

.[perex]
Ü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|neon:format] geschrieben. Zur Bearbeitung empfehlen wir [Editoren mit Unterstützung |best-practices:editors-and-tools#IDE-Editor] für dieses Format.

<pre>
"decorator .[prism-token prism-atrule]":[#Decorator]: 	"Decorator .[prism-token prism-comment]"<br>
"di .[prism-token prism-atrule]":[#DI]: 			"DI-Container .[prism-token prism-comment]"<br>
"extensions .[prism-token prism-atrule]":[#Erweiterungen]: 	"Installation weiterer DI-Erweiterungen .[prism-token prism-comment]"<br>
"includes .[prism-token prism-atrule]":[#Dateien einbinden]: 	"Einbinden von Dateien .[prism-token prism-comment]"<br>
"parameters .[prism-token prism-atrule]":[#Parameter]: 	"Parameter .[prism-token prism-comment]"<br>
"search .[prism-token prism-atrule]":[#Suche]: 		"Automatische Registrierung von Diensten .[prism-token prism-comment]"<br>
"services .[prism-token prism-atrule]":[services]: 		"Dienste .[prism-token prism-comment]"
</pre>

.[note]
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.

```neon
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:

```neon
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|services].


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.

```neon
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 |services#Tags] zu setzen oder den [inject |services#Inject-Modus]-Modus zu aktivieren.

```neon
decorator:
	InjectableInterface:
		tags: [mytag: 1]
		inject: true
```


DI
===

Technische Einstellungen des DI-Containers.

```neon
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 .{data-version:3.2.4}
----------------------------------

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 |services#Lazy Dienste].

.[note]
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.

```neon
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|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|application:bootstrapping], 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

```neon
extensions:
	dibi: Dibi\Bridges\Nette\DibiExtension22
```

Anschließend konfigurieren wir sie im Abschnitt `dibi`:

```neon
dibi:
	host: localhost
```

Als Erweiterung kann auch eine Klasse hinzugefügt werden, die Parameter hat:

```neon
extensions:
	application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, %appDir%, %tempDir%/cache)
```


Dateien einbinden
=================

Weitere Konfigurationsdateien können wir im Abschnitt `includes` einfügen:

```neon
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
<?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 |#Zusammenführen]. 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:

```neon
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:

```neon
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:


```neon
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:

```neon
search:
	-	in: %appDir%
		exclude:
			files: ...
			classes: ...
			extends: ...
			implements: ...
```

Für alle Dienste können Tags gesetzt werden:

```neon
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.

<table class=table>
<tr>
	<th width=33%>config1.neon</th>
	<th width=33%>config2.neon</th>
	<th>Ergebnis</th>
</tr>
<tr>
	<td>
```neon
items:
	- 1
	- 2
```
	</td>
	<td>
```neon
items:
	- 3
```
	</td>
	<td>
```neon
items:
	- 1
	- 2
	- 3
```
	</td>
</tr>
</table>

Bei Arrays kann das Zusammenführen durch Angabe eines Ausrufezeichens nach dem Schlüsselnamen verhindert werden:

<table class=table>
<tr>
	<th width=33%>config1.neon</th>
	<th width=33%>config2.neon</th>
	<th>Ergebnis</th>
</tr>
<tr>
	<td>
```neon
items:
	- 1
	- 2
```
	</td>
	<td>
```neon
items!:
	- 3
```
	</td>
	<td>
```neon
items:
	- 3
```
	</td>
</tr>
</table>

{{maintitle: Konfiguration der Dependency Injection}}

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
items:
	- 1
	- 2
items:
	- 3
items:
	- 1
	- 2
	- 3

Bei Arrays kann das Zusammenführen durch Angabe eines Ausrufezeichens nach dem Schlüsselnamen verhindert werden:

config1.neon config2.neon Ergebnis
items:
	- 1
	- 2
items!:
	- 3
items:
	- 3