Nette Documentation Preview

syntax
Konfiguracja kontenera DI
*************************

.[perex]
Przegląd opcji konfiguracyjnych kontenera Nette DI.


Plik konfiguracyjny
===================

Kontenerem Nette DI łatwo steruje się za pomocą plików konfiguracyjnych. Zapisywane są one zwykle w [formacie NEON|neon:format]. Zalecamy używanie [edytorów z jego obsługą |tools:ide].

<pre>
"decorator .[prism-token prism-atrule]":[#Dekorator]: 	"Dekorator .[prism-token prism-comment]"<br>
"di .[prism-token prism-atrule]":[#DI]: 			"Kontener DI .[prism-token prism-comment]"<br>
"extensions .[prism-token prism-atrule]":[#Rozszerzenia]: 	"Instalacja dodatkowych rozszerzeń DI .[prism-token prism-comment]"<br>
"includes .[prism-token prism-atrule]":[#Dołączanie plików]: 	"Dołączanie plików .[prism-token prism-comment]"<br>
"parameters .[prism-token prism-atrule]":[#Parametry]: 	"Parametry .[prism-token prism-comment]"<br>
"search .[prism-token prism-atrule]":[#Search]: 		"Automatyczna rejestracja usług .[prism-token prism-comment]"<br>
"services .[prism-token prism-atrule]":[services]: 		"Usługi .[prism-token prism-comment]"
</pre>

.[note]
Aby zapisać string zawierający znak `%`, musisz go zescapować, podwajając na `%%`.


Parametry
=========

W konfiguracji możesz zdefiniować parametry, których można potem używać jako części definicji usług. Pozwala to uczynić konfigurację czytelniejszą albo scentralizować wartości, które mogą się zmieniać.

```neon
parameters:
	dsn: 'mysql:host=127.0.0.1;dbname=test'
	user: root
	password: secret
```

Do parametru `dsn` odwołujemy się w dowolnym miejscu konfiguracji zapisem `%dsn%`. Parametrów można używać również wewnątrz stringów, jak `'%wwwDir%/images'`.

Parametry nie muszą być tylko stringami czy liczbami, mogą zawierać również tablice:

```neon
parameters:
	mailer:
		host: smtp.example.com
		secure: ssl
		user: franta@gmail.com
	languages: [cs, en, de]
```

Do konkretnego klucza odwołujemy się jako `%mailer.user%`.

Jeśli Twój kod (np. klasa) potrzebuje wartości parametru, przekaż mu ją. Na przykład w konstruktorze. Nie istnieje globalny obiekt konfiguracji, którego klasy mogłyby pytać o wartości parametrów. Byłoby to złamanie zasady wstrzykiwania zależności.


Usługi
======

Zobacz [osobny rozdział|services].


Dekorator
=========

Jak zmodyfikować naraz wiele usług określonego typu? Na przykład jak wywołać konkretną metodę na wszystkich presenterach dziedziczących po określonej klasie bazowej? Od tego jest dekorator.

```neon
decorator:
	# dla wszystkich usług będących instancjami tej klasy albo interfejsu
	App\Presentation\BasePresenter:
		setup:
			- setProjectId(10)       # wywołaj tę metodę
			- $absoluteUrls = true   # i ustaw zmienną
```

Dekoratora można też używać do ustawiania [tagów |services#Tagi] albo włączania [trybu inject |services#Tryb inject].

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


DI
===

Ustawienia techniczne kontenera DI.

```neon
di:
	# pokazywać DIC w pasku Tracy?
	debugger: ...        # (bool) domyślnie autodetekcja (włączone, gdy Tracy jest obecne)

	# typy parametrów, których nigdy nie autowirujesz
	excluded: ...        # (string[])

	# włączyć leniwe tworzenie usług?
	lazy: ...            # (bool) domyślnie false

	# klasa, po której dziedziczy kontener DI
	parentClass: ...     # (string) domyślnie Nette\DI\Container
```


Usługi leniwe .{data-version:3.2.4}
-----------------------------------

Ustawienie `lazy: true` aktywuje leniwe (odroczone) tworzenie usług. Oznacza to, że usługi nie są faktycznie tworzone w chwili, gdy prosisz o nie kontener DI, lecz dopiero przy ich pierwszym użyciu. Może to przyspieszyć start aplikacji i zmniejszyć zużycie pamięci, bo tworzone są tylko usługi faktycznie potrzebne dla danego żądania.

Dla konkretnej usługi leniwe tworzenie można [dostosować |services#Usługi leniwe].

.[note]
Obiektów leniwych można używać tylko dla klas zdefiniowanych przez użytkownika, nie dla wewnętrznych klas PHP. Wymaga PHP 8.4 lub nowszego.


Eksport metadanych
------------------

Klasa kontenera DI zawiera również sporo metadanych. Możesz zmniejszyć jej rozmiar, ograniczając eksport metadanych.

```neon
di:
	export:
		# eksportować parametry?
		parameters: false   # (bool) domyślnie true

		# eksportować tagi i które?
		tags:               # (string[]|bool) domyślnie wszystkie
			- event.subscriber

		# eksportować dane do autowiringu i które?
		types:              # (string[]|bool) domyślnie wszystkie
			- Nette\Database\Connection
			- Symfony\Component\Console\Application
```

Jeśli nie używasz `$container->getParameters()`, możesz wyłączyć eksport parametrów. Ponadto możesz eksportować tylko te tagi, których faktycznie używasz do pobierania usług przez `$container->findByTag(...)`. Jeśli w ogóle nie wywołujesz tej metody, możesz całkowicie wyłączyć eksport tagów przez `false`.

Możesz znacząco ograniczyć metadane dla [autowiringu|autowiring], wymieniając tylko te klasy, o które faktycznie prosisz przez `$container->getByType()`. Znów: jeśli nie wywołujesz tej metody (albo wywołujesz ją tylko w pliku [bootstrap|application:bootstrapping], np. aby uzyskać `Nette\Application\Application`), możesz całkowicie wyłączyć eksport typów przez `false`.


Rozszerzenia
============

Rejestracja dodatkowych rozszerzeń DI. Tak dodasz na przykład rozszerzenie DI `Dibi\Bridges\Nette\DibiExtension3` pod nazwą `dibi`:

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

Konfigurujesz je potem w sekcji `dibi`:

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

Jako rozszerzenie możesz też dodać klasę z parametrami:

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


Dołączanie plików
=================

Kolejne pliki konfiguracyjne można dołączyć w sekcji `includes`:

```neon
includes:
	- parameters.php
	- services.neon
	- presenters.neon
```

Nazwa `parameters.php` nie jest literówką; konfigurację można zapisać także w pliku PHP, który zwraca ją jako tablicę:

```php
<?php
return [
	'database' => [
		'main' => [
			'dsn' => 'sqlite::memory:',
		],
	],
];
```

Jeśli elementy o tych samych kluczach pojawią się w kilku plikach konfiguracyjnych, zostaną nadpisane albo, w przypadku tablic, [scalone |#Scalanie]. Plik dołączony później ma wyższy priorytet niż poprzedni. Plik, w którym wymieniona jest sekcja `includes`, ma wyższy priorytet niż pliki w nim dołączone.


Search
======

Automatyczna rejestracja usług w kontenerze DI znacząco upraszcza pracę. Nette automatycznie dodaje do kontenera presentery, ale równie łatwo dodasz dowolne inne klasy.

Wystarczy podać, w których katalogach (i podkatalogach) mają być wyszukiwane klasy:

```neon
search:
	-	in: %appDir%/Forms
	-	in: %appDir%/Model
```

Jeśli potrzebujesz tylko jednej reguły wyszukiwania, możesz pominąć listę i zapisać jej klucze bezpośrednio pod `search`:

```neon
search:
	in: %appDir%
```

Zwykle jednak nie chcemy dodawać absolutnie wszystkich klas i interfejsów, więc możemy je filtrować:

```neon
search:
	-	in: %appDir%/Forms

		# filtrowanie po nazwie pliku (string|string[])
		files:
			- *Factory.php

		# filtrowanie po nazwie klasy (string|string[])
		classes:
			- *Factory
```

Albo możemy wybrać klasy, które dziedziczą po co najmniej jednej z wymienionych klas albo ją implementują:


```neon
search:
	-	in: %appDir%
		extends:
			- App\*Form
		implements:
			- App\*FormInterface
```

Możesz też zdefiniować reguły wykluczające za pomocą masek nazw klas albo przodków. Jeśli klasa pasuje do reguły wykluczającej, nie zostanie dodana do kontenera DI:

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

Wszystkim automatycznie zarejestrowanym usługom można przypisać tagi:

```neon
search:
	-	in: %appDir%
		tags: ...
```

Poza klasami search rejestruje również interfejsy mające jedną metodę `create()` albo `get()` - jako [generowane fabryki albo akcesory |factory]. Klasy, dla których w kontenerze zarejestrowana jest już usługa tego samego typu, są pomijane, więc nie powstają duplikaty.


Scalanie
========

Jeśli elementy o tych samych kluczach pojawią się w kilku plikach konfiguracyjnych, zostaną nadpisane albo, w przypadku tablic, scalone. Plik dołączony później ma wyższy priorytet niż poprzedni.

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

Dla tablic scalaniu można zapobiec, dodając po nazwie klucza wykrzyknik:

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

{{maintitle: Konfiguracja wstrzykiwania zależności}}

Konfiguracja kontenera DI

Przegląd opcji konfiguracyjnych kontenera Nette DI.

Plik konfiguracyjny

Kontenerem Nette DI łatwo steruje się za pomocą plików konfiguracyjnych. Zapisywane są one zwykle w formacie NEON. Zalecamy używanie edytorów z jego obsługą.

 decorator: 	Dekorator
di: Kontener DI
extensions: Instalacja dodatkowych rozszerzeń DI
includes: Dołączanie plików
parameters: Parametry
search: Automatyczna rejestracja usług
services: Usługi

Aby zapisać string zawierający znak %, musisz go zescapować, podwajając na %%.

Parametry

W konfiguracji możesz zdefiniować parametry, których można potem używać jako części definicji usług. Pozwala to uczynić konfigurację czytelniejszą albo scentralizować wartości, które mogą się zmieniać.

parameters:
	dsn: 'mysql:host=127.0.0.1;dbname=test'
	user: root
	password: secret

Do parametru dsn odwołujemy się w dowolnym miejscu konfiguracji zapisem %dsn%. Parametrów można używać również wewnątrz stringów, jak '%wwwDir%/images'.

Parametry nie muszą być tylko stringami czy liczbami, mogą zawierać również tablice:

parameters:
	mailer:
		host: smtp.example.com
		secure: ssl
		user: franta@gmail.com
	languages: [cs, en, de]

Do konkretnego klucza odwołujemy się jako %mailer.user%.

Jeśli Twój kod (np. klasa) potrzebuje wartości parametru, przekaż mu ją. Na przykład w konstruktorze. Nie istnieje globalny obiekt konfiguracji, którego klasy mogłyby pytać o wartości parametrów. Byłoby to złamanie zasady wstrzykiwania zależności.

Usługi

Zobacz osobny rozdział.

Dekorator

Jak zmodyfikować naraz wiele usług określonego typu? Na przykład jak wywołać konkretną metodę na wszystkich presenterach dziedziczących po określonej klasie bazowej? Od tego jest dekorator.

decorator:
	# dla wszystkich usług będących instancjami tej klasy albo interfejsu
	App\Presentation\BasePresenter:
		setup:
			- setProjectId(10)       # wywołaj tę metodę
			- $absoluteUrls = true   # i ustaw zmienną

Dekoratora można też używać do ustawiania tagów albo włączania trybu inject.

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

DI

Ustawienia techniczne kontenera DI.

di:
	# pokazywać DIC w pasku Tracy?
	debugger: ...        # (bool) domyślnie autodetekcja (włączone, gdy Tracy jest obecne)

	# typy parametrów, których nigdy nie autowirujesz
	excluded: ...        # (string[])

	# włączyć leniwe tworzenie usług?
	lazy: ...            # (bool) domyślnie false

	# klasa, po której dziedziczy kontener DI
	parentClass: ...     # (string) domyślnie Nette\DI\Container

Usługi leniwe

Ustawienie lazy: true aktywuje leniwe (odroczone) tworzenie usług. Oznacza to, że usługi nie są faktycznie tworzone w chwili, gdy prosisz o nie kontener DI, lecz dopiero przy ich pierwszym użyciu. Może to przyspieszyć start aplikacji i zmniejszyć zużycie pamięci, bo tworzone są tylko usługi faktycznie potrzebne dla danego żądania.

Dla konkretnej usługi leniwe tworzenie można dostosować.

Obiektów leniwych można używać tylko dla klas zdefiniowanych przez użytkownika, nie dla wewnętrznych klas PHP. Wymaga PHP 8.4 lub nowszego.

Eksport metadanych

Klasa kontenera DI zawiera również sporo metadanych. Możesz zmniejszyć jej rozmiar, ograniczając eksport metadanych.

di:
	export:
		# eksportować parametry?
		parameters: false   # (bool) domyślnie true

		# eksportować tagi i które?
		tags:               # (string[]|bool) domyślnie wszystkie
			- event.subscriber

		# eksportować dane do autowiringu i które?
		types:              # (string[]|bool) domyślnie wszystkie
			- Nette\Database\Connection
			- Symfony\Component\Console\Application

Jeśli nie używasz $container->getParameters(), możesz wyłączyć eksport parametrów. Ponadto możesz eksportować tylko te tagi, których faktycznie używasz do pobierania usług przez $container->findByTag(...). Jeśli w ogóle nie wywołujesz tej metody, możesz całkowicie wyłączyć eksport tagów przez false.

Możesz znacząco ograniczyć metadane dla autowiringu, wymieniając tylko te klasy, o które faktycznie prosisz przez $container->getByType(). Znów: jeśli nie wywołujesz tej metody (albo wywołujesz ją tylko w pliku bootstrap, np. aby uzyskać Nette\Application\Application), możesz całkowicie wyłączyć eksport typów przez false.

Rozszerzenia

Rejestracja dodatkowych rozszerzeń DI. Tak dodasz na przykład rozszerzenie DI Dibi\Bridges\Nette\DibiExtension3 pod nazwą dibi:

extensions:
	dibi: Dibi\Bridges\Nette\DibiExtension3

Konfigurujesz je potem w sekcji dibi:

dibi:
	host: localhost

Jako rozszerzenie możesz też dodać klasę z parametrami:

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

Dołączanie plików

Kolejne pliki konfiguracyjne można dołączyć w sekcji includes:

includes:
	- parameters.php
	- services.neon
	- presenters.neon

Nazwa parameters.php nie jest literówką; konfigurację można zapisać także w pliku PHP, który zwraca ją jako tablicę:

<?php
return [
	'database' => [
		'main' => [
			'dsn' => 'sqlite::memory:',
		],
	],
];

Jeśli elementy o tych samych kluczach pojawią się w kilku plikach konfiguracyjnych, zostaną nadpisane albo, w przypadku tablic, scalone. Plik dołączony później ma wyższy priorytet niż poprzedni. Plik, w którym wymieniona jest sekcja includes, ma wyższy priorytet niż pliki w nim dołączone.

Automatyczna rejestracja usług w kontenerze DI znacząco upraszcza pracę. Nette automatycznie dodaje do kontenera presentery, ale równie łatwo dodasz dowolne inne klasy.

Wystarczy podać, w których katalogach (i podkatalogach) mają być wyszukiwane klasy:

search:
	-	in: %appDir%/Forms
	-	in: %appDir%/Model

Jeśli potrzebujesz tylko jednej reguły wyszukiwania, możesz pominąć listę i zapisać jej klucze bezpośrednio pod search:

search:
	in: %appDir%

Zwykle jednak nie chcemy dodawać absolutnie wszystkich klas i interfejsów, więc możemy je filtrować:

search:
	-	in: %appDir%/Forms

		# filtrowanie po nazwie pliku (string|string[])
		files:
			- *Factory.php

		# filtrowanie po nazwie klasy (string|string[])
		classes:
			- *Factory

Albo możemy wybrać klasy, które dziedziczą po co najmniej jednej z wymienionych klas albo ją implementują:

search:
	-	in: %appDir%
		extends:
			- App\*Form
		implements:
			- App\*FormInterface

Możesz też zdefiniować reguły wykluczające za pomocą masek nazw klas albo przodków. Jeśli klasa pasuje do reguły wykluczającej, nie zostanie dodana do kontenera DI:

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

Wszystkim automatycznie zarejestrowanym usługom można przypisać tagi:

search:
	-	in: %appDir%
		tags: ...

Poza klasami search rejestruje również interfejsy mające jedną metodę create() albo get() – jako generowane fabryki albo akcesory. Klasy, dla których w kontenerze zarejestrowana jest już usługa tego samego typu, są pomijane, więc nie powstają duplikaty.

Scalanie

Jeśli elementy o tych samych kluczach pojawią się w kilku plikach konfiguracyjnych, zostaną nadpisane albo, w przypadku tablic, scalone. Plik dołączony później ma wyższy priorytet niż poprzedni.

config1.neon config2.neon wynik
items:
	- 1
	- 2
items:
	- 3
items:
	- 1
	- 2
	- 3

Dla tablic scalaniu można zapobiec, dodając po nazwie klucza wykrzyknik:

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