Nette Documentation Preview

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

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


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

Kontener Nette DI łatwo się kontroluje za pomocą plików konfiguracyjnych. Zazwyczaj są one zapisywane w [formacie NEON|neon:format]. Do edycji polecamy [edytory z obsługą |best-practices:editors-and-tools#Edytor IDE] tego formatu.

<pre>
"decorator .[prism-token prism-atrule]":[#decorator]: 	"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ć ciąg znaków zawierający znak `%`, musisz go escapować podwajając na `%%`.


Parametry
=========

W konfiguracji możesz zdefiniować parametry, które można następnie użyć jako część definicji usług. Dzięki temu możesz uporządkować konfigurację lub ujednolicić i wyodrębnić wartości, które będą 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%`. Parametry można używać również wewnątrz ciągów znaków, jak `'%wwwDir%/images'`.

Parametry nie muszą być tylko ciągami znaków lub liczbami, mogą również zawierać 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 potrzebujesz w swoim kodzie, na przykład w klasie, poznać wartość dowolnego parametru, przekaż go do tej klasy. Na przykład w konstruktorze. Nie istnieje żaden globalny obiekt reprezentujący konfigurację, którego klasy pytałyby o wartości parametrów. Byłoby to naruszeniem zasady wstrzykiwania zależności.


Usługi
======

Zobacz [osobny rozdział|services].


Decorator
=========

Jak masowo modyfikować wszystkie usługi określonego typu? Na przykład wywołać określoną metodę u wszystkich prezenterów, które dziedziczą po konkretnym wspólnym przodku? Do tego służy dekorator.

```neon
decorator:
	# dla wszystkich usług, które są instancją tej klasy lub interfejsu
	App\Presentation\BasePresenter:
		setup:
			- setProjectId(10)       # wywołaj tę metodę
			- $absoluteUrls = true   # i ustaw zmienną
```

Dekorator można również używać do ustawiania [tagów |services#Tagi] lub włączania trybu [inject |services#Tryb Inject].

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


DI
===

Techniczne ustawienia kontenera DI.

```neon
di:
	# wyświetlać DIC w Tracy Bar?
	debugger: ...        # (bool) domyślnie true

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

	# zezwolić na lazy tworzenie usług?
	lazy: ...            # (bool) domyślnie false

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


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

Ustawienie `lazy: true` aktywuje lazy (odroczone) tworzenie usług. Oznacza to, że usługi nie są faktycznie tworzone w momencie, gdy żądamy ich z kontenera DI, ale dopiero w chwili ich pierwszego użycia. Może to przyspieszyć start aplikacji i zmniejszyć zużycie pamięci, ponieważ tworzone są tylko te usługi, które są faktycznie potrzebne w danym żądaniu.

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

.[note]
Obiekty lazy można używać tylko dla klas użytkownika, a nie dla wewnętrznych klas PHP. Wymaga PHP 8.4 lub nowszego.


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

Klasa kontenera DI zawiera również wiele metadanych. Możesz ją zmniejszyć, redukują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 dla autowiringu i które?
		types:              # (string[]|bool) domyślnie wszystkie
			- Nette\Database\Connection
			- Symfony\Component\Console\Application
```

Jeśli nie używasz tablicy `$container->getParameters()`, możesz wyłączyć eksport parametrów. Ponadto możesz eksportować tylko te tagi, za pomocą których uzyskujesz usługi metodą `$container->findByTag(...)`. Jeśli metody nie wywołujesz w ogóle, możesz całkowicie wyłączyć eksport tagów za pomocą `false`.

Możesz znacznie zredukować metadane dla [autowiringu |autowiring] podając klasy, których używasz jako parametr metody `$container->getByType()`. I ponownie, jeśli metody nie wywołujesz w ogóle (lub tylko w [bootstrapie|application:bootstrapping] do uzyskania `Nette\Application\Application`), możesz eksport całkowicie wyłączyć za pomocą `false`.


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

Rejestracja dodatkowych rozszerzeń DI. W ten sposób dodajemy np. rozszerzenie DI `Dibi\Bridges\Nette\DibiExtension22` pod nazwą `dibi`

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

Następnie konfigurujemy je w sekcji `dibi`:

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

Jako rozszerzenie można dodać również klasę, która ma parametry:

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


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

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

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

Nazwa `parameters.php` nie jest literówką, konfiguracja może być zapisana również w pliku PHP, który zwróci ją jako tablicę:

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

Jeśli w plikach konfiguracyjnych pojawią się elementy o tych samych kluczach, zostaną nadpisane, lub w przypadku [tablic połączone |#Łączenie]. Później dołączany plik ma wyższy priorytet niż poprzedni. Plik, w którym znajduje się sekcja `includes`, ma wyższy priorytet niż w nim dołączane pliki.


Search
======

Automatyczne dodawanie usług do kontenera DI niezwykle ułatwia pracę. Nette automatycznie dodaje do kontenera presentery, ale można łatwo dodawać również dowolne inne klasy.

Wystarczy podać, w których katalogach (i podkatalogach) ma szukać klas:

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

Zazwyczaj jednak nie chcemy dodawać absolutnie wszystkich klas i interfejsów, dlatego możemy je filtrować:

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

		# filtrowanie według nazwy pliku (string|string[])
		files:
			- *Factory.php

		# filtrowanie według nazwy klasy (string|string[])
		classes:
			- *Factory
```

Lub możemy wybierać klasy, które dziedziczą lub implementują co najmniej jedną z podanych klas:


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

Można zdefiniować również reguły wykluczające, tj. maski nazwy klasy lub przodków dziedziczenia, które jeśli pasują, usługa nie zostanie dodana do kontenera DI:

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

Wszystkim usługom można ustawić tagi:

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


Łączenie
========

Jeśli w wielu plikach konfiguracyjnych pojawią się elementy o tych samych kluczach, zostaną nadpisane, lub w przypadku tablic połączone. Później dołączany plik 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>

W przypadku tablic można zapobiec łączeniu, dodając wykrzyknik za nazwą klucza:

<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 Dependency Injection}}

Konfiguracja kontenera DI

Przegląd opcji konfiguracyjnych dla kontenera Nette DI.

Plik konfiguracyjny

Kontener Nette DI łatwo się kontroluje za pomocą plików konfiguracyjnych. Zazwyczaj są one zapisywane w formacie NEON. Do edycji polecamy edytory z obsługą tego formatu.

 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ć ciąg znaków zawierający znak %, musisz go escapować podwajając na %%.

Parametry

W konfiguracji możesz zdefiniować parametry, które można następnie użyć jako część definicji usług. Dzięki temu możesz uporządkować konfigurację lub ujednolicić i wyodrębnić wartości, które będą 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%. Parametry można używać również wewnątrz ciągów znaków, jak '%wwwDir%/images'.

Parametry nie muszą być tylko ciągami znaków lub liczbami, mogą również zawierać 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 potrzebujesz w swoim kodzie, na przykład w klasie, poznać wartość dowolnego parametru, przekaż go do tej klasy. Na przykład w konstruktorze. Nie istnieje żaden globalny obiekt reprezentujący konfigurację, którego klasy pytałyby o wartości parametrów. Byłoby to naruszeniem zasady wstrzykiwania zależności.

Usługi

Zobacz osobny rozdział.

Decorator

Jak masowo modyfikować wszystkie usługi określonego typu? Na przykład wywołać określoną metodę u wszystkich prezenterów, które dziedziczą po konkretnym wspólnym przodku? Do tego służy dekorator.

decorator:
	# dla wszystkich usług, które są instancją tej klasy lub interfejsu
	App\Presentation\BasePresenter:
		setup:
			- setProjectId(10)       # wywołaj tę metodę
			- $absoluteUrls = true   # i ustaw zmienną

Dekorator można również używać do ustawiania tagów lub włączania trybu inject.

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

DI

Techniczne ustawienia kontenera DI.

di:
	# wyświetlać DIC w Tracy Bar?
	debugger: ...        # (bool) domyślnie true

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

	# zezwolić na lazy tworzenie usług?
	lazy: ...            # (bool) domyślnie false

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

Usługi lazy

Ustawienie lazy: true aktywuje lazy (odroczone) tworzenie usług. Oznacza to, że usługi nie są faktycznie tworzone w momencie, gdy żądamy ich z kontenera DI, ale dopiero w chwili ich pierwszego użycia. Może to przyspieszyć start aplikacji i zmniejszyć zużycie pamięci, ponieważ tworzone są tylko te usługi, które są faktycznie potrzebne w danym żądaniu.

Dla konkretnej usługi można zmienić lazy tworzenie.

Obiekty lazy można używać tylko dla klas użytkownika, a nie dla wewnętrznych klas PHP. Wymaga PHP 8.4 lub nowszego.

Eksport metadanych

Klasa kontenera DI zawiera również wiele metadanych. Możesz ją zmniejszyć, redukują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 dla autowiringu i które?
		types:              # (string[]|bool) domyślnie wszystkie
			- Nette\Database\Connection
			- Symfony\Component\Console\Application

Jeśli nie używasz tablicy $container->getParameters(), możesz wyłączyć eksport parametrów. Ponadto możesz eksportować tylko te tagi, za pomocą których uzyskujesz usługi metodą $container->findByTag(...). Jeśli metody nie wywołujesz w ogóle, możesz całkowicie wyłączyć eksport tagów za pomocą false.

Możesz znacznie zredukować metadane dla autowiringu podając klasy, których używasz jako parametr metody $container->getByType(). I ponownie, jeśli metody nie wywołujesz w ogóle (lub tylko w bootstrapie do uzyskania Nette\Application\Application), możesz eksport całkowicie wyłączyć za pomocą false.

Rozszerzenia

Rejestracja dodatkowych rozszerzeń DI. W ten sposób dodajemy np. rozszerzenie DI Dibi\Bridges\Nette\DibiExtension22 pod nazwą dibi

extensions:
	dibi: Dibi\Bridges\Nette\DibiExtension22

Następnie konfigurujemy je w sekcji dibi:

dibi:
	host: localhost

Jako rozszerzenie można dodać również klasę, która ma parametry:

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

Dołączanie plików

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

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

Nazwa parameters.php nie jest literówką, konfiguracja może być zapisana również w pliku PHP, który zwróci ją jako tablicę:

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

Jeśli w plikach konfiguracyjnych pojawią się elementy o tych samych kluczach, zostaną nadpisane, lub w przypadku tablic połączone. Później dołączany plik ma wyższy priorytet niż poprzedni. Plik, w którym znajduje się sekcja includes, ma wyższy priorytet niż w nim dołączane pliki.

Automatyczne dodawanie usług do kontenera DI niezwykle ułatwia pracę. Nette automatycznie dodaje do kontenera presentery, ale można łatwo dodawać również dowolne inne klasy.

Wystarczy podać, w których katalogach (i podkatalogach) ma szukać klas:

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

Zazwyczaj jednak nie chcemy dodawać absolutnie wszystkich klas i interfejsów, dlatego możemy je filtrować:

search:
	-	in: %appDir%/Forms

		# filtrowanie według nazwy pliku (string|string[])
		files:
			- *Factory.php

		# filtrowanie według nazwy klasy (string|string[])
		classes:
			- *Factory

Lub możemy wybierać klasy, które dziedziczą lub implementują co najmniej jedną z podanych klas:

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

Można zdefiniować również reguły wykluczające, tj. maski nazwy klasy lub przodków dziedziczenia, które jeśli pasują, usługa nie zostanie dodana do kontenera DI:

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

Wszystkim usługom można ustawić tagi:

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

Łączenie

Jeśli w wielu plikach konfiguracyjnych pojawią się elementy o tych samych kluczach, zostaną nadpisane, lub w przypadku tablic połączone. Później dołączany plik ma wyższy priorytet niż poprzedni.

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

W przypadku tablic można zapobiec łączeniu, dodając wykrzyknik za nazwą klucza:

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