DI konténer konfigurációja

A Nette DI konténer konfigurációs opcióinak áttekintése.

Konfigurációs fájl

A Nette DI konténer könnyen vezérelhető konfigurációs fájlok segítségével. Ezek általában NEON formátumban íródnak. A szerkesztéshez támogatással rendelkező szerkesztőket ajánlunk ehhez a formátumhoz.

 decorator: 	Dekorátor
di: DI konténer
extensions: További DI kiterjesztések telepítése
includes: Fájlok beillesztése
parameters: Paraméterek
search: Szolgáltatások automatikus regisztrálása
services: Szolgáltatások

Ha % karaktert tartalmazó stringet szeretne írni, duplázással kell escapelni %%-ra.

Paraméterek

A konfigurációban definiálhat paramétereket, amelyeket aztán a szolgáltatásdefiníciók részeként használhat. Ezzel áttekinthetőbbé teheti a konfigurációt, vagy egységesítheti és kiemelheti azokat az értékeket, amelyek változni fognak.

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

A dsn paraméterre bárhol a konfigurációban %dsn% írással hivatkozhatunk. A paramétereket stringeken belül is használhatjuk, mint például '%wwwDir%/images'.

A paraméterek nem csak stringek vagy számok lehetnek, tartalmazhatnak tömböket is:

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

Egy konkrét kulcsra %mailer.user%-ként hivatkozhatunk.

Ha a kódjában, például egy osztályban, meg kell tudnia bármely paraméter értékét, adja át azt ennek az osztálynak. Például a konstruktorban. Nincs globális objektum, amely a konfigurációt képviselné, és amelytől az osztályok lekérdeznék a paraméterértékeket. Ez megsértené a dependency injection elvét.

Szolgáltatások

Lásd a külön fejezetben.

Decorator

Hogyan lehet tömegesen módosítani egy adott típusú összes szolgáltatást? Például meghívni egy bizonyos metódust minden olyan presenter esetén, amely egy konkrét közös őstől öröklődik? Erre való a decorator.

decorator:
	# minden olyan szolgáltatásnál, amely ennek az osztálynak vagy interfésznek a példánya
	App\Presentation\BasePresenter:
		setup:
			- setProjectId(10)       # hívd meg ezt a metódust
			- $absoluteUrls = true   # és állítsd be a változót

A decorator használható tagekkel beállítására vagy az inject mód bekapcsolására is.

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

DI

A DI konténer technikai beállításai.

di:
	# megjeleníteni a DIC-t a Tracy Bar-ban?
	debugger: ...        # (bool) alapértelmezett true

	# soha nem autowire-olandó paramétertípusok
	excluded: ...        # (string[])

	# engedélyezni a szolgáltatások lazy létrehozását?
	lazy: ...            # (bool) alapértelmezett false

	# osztály, amelytől a DI konténer öröklődik
	parentClass: ...     # (string) alapértelmezett Nette\DI\Container

Lazy szolgáltatások

A lazy: true beállítás aktiválja a szolgáltatások lazy (késleltetett) létrehozását. Ez azt jelenti, hogy a szolgáltatások nem jönnek létre ténylegesen abban a pillanatban, amikor lekérjük őket a DI konténerből, hanem csak az első használatuk pillanatában. Ez gyorsíthatja az alkalmazás indítását és csökkentheti a memóriaterhelést, mivel csak azok a szolgáltatások jönnek létre, amelyekre az adott kérésben valóban szükség van.

Egy konkrét szolgáltatásnál a lazy létrehozást módosítani lehet.

A lazy objektumok csak felhasználói osztályokhoz használhatók, nem belső PHP osztályokhoz. PHP 8.4 vagy újabb verziót igényel.

Metaadatok exportálása

A DI konténer osztálya sok metaadatot is tartalmaz. Csökkentheti a méretét azáltal, hogy redukálja a metaadatok exportálását.

di:
	export:
		# exportálni a paramétereket?
		parameters: false   # (bool) alapértelmezett true

		# exportálni a tageket és melyeket?
		tags:               # (string[]|bool) alapértelmezés szerint mindet
			- event.subscriber

		# exportálni az autowiring adatokat és melyeket?
		types:              # (string[]|bool) alapértelmezés szerint mindet
			- Nette\Database\Connection
			- Symfony\Component\Console\Application

Ha nem használja a $container->getParameters() tömböt, kikapcsolhatja a paraméterek exportálását. Továbbá exportálhatja csak azokat a tageket, amelyeken keresztül szolgáltatásokat szerez a $container->findByTag(...) metódussal. Ha egyáltalán nem hívja meg a metódust, teljesen kikapcsolhatja a tagek exportálását false-szal.

Jelentősen redukálhatja az autowiring metaadatait azáltal, hogy megadja azokat az osztályokat, amelyeket a $container->getByType() metódus paramétereként használ. És ismét, ha egyáltalán nem hívja meg a metódust (illetve csak a bootstrapban a Nette\Application\Application megszerzéséhez), teljesen kikapcsolhatja az exportálást false-szal.

Kiterjesztések

További DI kiterjesztések regisztrálása. Ezzel a módszerrel hozzáadjuk például a Dibi\Bridges\Nette\DibiExtension22 DI kiterjesztést dibi néven.

extensions:
	dibi: Dibi\Bridges\Nette\DibiExtension22

Ezután a dibi szekcióban konfiguráljuk:

dibi:
	host: localhost

Kiterjesztésként hozzá lehet adni egy osztályt is, amelynek paraméterei vannak:

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

Fájlok beillesztése

További konfigurációs fájlokat illeszthetünk be az includes szekcióban:

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

A parameters.php név nem elírás, a konfiguráció PHP fájlban is leírható, amely tömbként adja vissza:

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

Ha a konfigurációs fájlokban azonos kulcsokkal rendelkező elemek jelennek meg, felülíródnak, vagy tömbök esetén egyesítve lesznek. A később beillesztett fájl magasabb prioritású, mint az előző. Az a fájl, amelyben az includes szekció szerepel, magasabb prioritású, mint a benne beillesztett fájlok.

A szolgáltatások automatikus hozzáadása a DI konténerhez rendkívül megkönnyíti a munkát. A Nette automatikusan hozzáadja a presentereket a konténerhez, de könnyen hozzáadhat bármilyen más osztályt is.

Csak meg kell adni, mely könyvtárakban (és alkönyvtárakban) keresse az osztályokat:

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

Általában azonban nem akarjuk hozzáadni az összes osztályt és interfészt, ezért szűrhetjük őket:

search:
	-	in: %appDir%/Forms

		# szűrés fájlnév alapján (string|string[])
		files:
			- *Factory.php

		# szűrés osztálynév alapján (string|string[])
		classes:
			- *Factory

Vagy kiválaszthatunk olyan osztályokat, amelyek legalább egyet örökölnek vagy implementálnak a megadott osztályok közül:

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

Definiálhatunk kizáró szabályokat is, azaz osztálynév maszkokat vagy örökölt ősöket, amelyek ha megfelelnek, a szolgáltatás nem kerül hozzáadásra a DI konténerhez:

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

Minden szolgáltatáshoz be lehet állítani tageket:

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

Összefésülés

Ha több konfigurációs fájlban azonos kulcsokkal rendelkező elemek jelennek meg, felülíródnak, vagy tömbök esetén összefésülődnek. A később beillesztett fájl magasabb prioritású, mint az előző.

config1.neon config2.neon eredmény
items:
	- 1
	- 2
items:
	- 3
items:
	- 1
	- 2
	- 3

Tömbök esetén megakadályozható az összefésülés egy felkiáltójel hozzáadásával a kulcs neve után:

config1.neon config2.neon eredmény
items:
	- 1
	- 2
items!:
	- 3
items:
	- 3
verzió: 3.x