Configurarea containerului DI

Prezentare generală a opțiunilor de configurare pentru containerul Nette DI.

Fișier de configurare

Containerul Nette DI este ușor de controlat folosind fișiere de configurare. Acestea sunt de obicei scrise în formatul NEON. Pentru editare, recomandăm editoare cu suport pentru acest format.

 decorator: 	Decorator
di: Container DI
extensions: Instalarea altor extensii DI
includes: Includerea fișierelor
parameters: Parametri
search: Înregistrarea automată a serviciilor
services: Servicii

Pentru a scrie un șir care conține caracterul %, trebuie să îl escapați dublându-l la %%.

Parametri

În configurație puteți defini parametri care pot fi apoi utilizați ca parte a definițiilor serviciilor. Astfel puteți clarifica configurația sau puteți unifica și extrage valorile care se vor modifica.

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

Ne referim la parametrul dsn oriunde în configurație scriind %dsn%. Parametrii pot fi utilizați și în interiorul șirurilor precum '%wwwDir%/images'.

Parametrii nu trebuie să fie doar șiruri sau numere, pot conține și array-uri:

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

Ne referim la cheia specifică ca %mailer.user%.

Dacă aveți nevoie în codul dvs., de exemplu într-o clasă, să aflați valoarea oricărui parametru, transmiteți-l acelei clase. De exemplu, în constructor. Nu există niciun obiect global care să reprezinte configurația, pe care clasele să îl interogheze pentru valorile parametrilor. Acest lucru ar încălca principiul injecției de dependență.

Servicii

Vezi capitolul separat.

Decorator

Cum să modificați în masă toate serviciile de un anumit tip? De exemplu, să apelați o anumită metodă la toți presenterii care moștenesc de la un anumit strămoș comun? Pentru asta există decoratorul.

decorator:
	# pentru toate serviciile care sunt instanțe ale acestei clase sau interfețe
	App\Presentation\BasePresenter:
		setup:
			- setProjectId(10)       # apelează această metodă
			- $absoluteUrls = true   # și setează variabila

Decoratorul poate fi utilizat și pentru setarea tag-urilor sau activarea modului inject.

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

DI

Setări tehnice ale containerului DI.

di:
	# afișează DIC în Tracy Bar?
	debugger: ...        # (bool) implicit este true

	# tipuri de parametri care nu se autowirează niciodată
	excluded: ...        # (string[])

	# permite crearea lazy a serviciilor?
	lazy: ...            # (bool) implicit este false

	# clasa de la care moștenește containerul DI
	parentClass: ...     # (string) implicit este Nette\DI\Container

Servicii lazy

Setarea lazy: true activează crearea lazy (amânată) a serviciilor. Acest lucru înseamnă că serviciile nu sunt create efectiv în momentul în care le solicităm din containerul DI, ci abia în momentul primei lor utilizări. Acest lucru poate accelera pornirea aplicației și reduce cerințele de memorie, deoarece se creează doar serviciile care sunt efectiv necesare în request-ul respectiv.

Pentru un serviciu specific, crearea lazy poate fi modificată.

Obiectele lazy pot fi utilizate doar pentru clasele utilizatorului, nu și pentru clasele interne PHP. Necesită PHP 8.4 sau o versiune mai recentă.

Export metadate

Clasa containerului DI conține și multe metadate. Puteți reduce dimensiunea acesteia prin reducerea exportului de metadate.

di:
	export:
		# exportă parametrii?
		parameters: false   # (bool) implicit este true

		# exportă tag-urile și care anume?
		tags:               # (string[]|bool) implicit sunt toate
			- event.subscriber

		# exportă datele pentru autowiring și care anume?
		types:              # (string[]|bool) implicit sunt toate
			- Nette\Database\Connection
			- Symfony\Component\Console\Application

Dacă nu utilizați array-ul $container->getParameters(), puteți dezactiva exportul parametrilor. În plus, puteți exporta doar acele tag-uri prin care obțineți servicii folosind metoda $container->findByTag(...). Dacă nu apelați deloc metoda, puteți dezactiva complet exportul tag-urilor folosind false.

Puteți reduce semnificativ metadatele pentru autowiring specificând clasele pe care le utilizați ca parametru al metodei $container->getByType(). Și din nou, dacă nu apelați deloc metoda (respectiv doar în bootstrap pentru a obține Nette\Application\Application), puteți dezactiva complet exportul folosind false.

Extensii

Înregistrarea altor extensii DI. În acest fel adăugăm, de exemplu, extensia DI Dibi\Bridges\Nette\DibiExtension22 sub numele dibi

extensions:
	dibi: Dibi\Bridges\Nette\DibiExtension22

Ulterior, o configurăm în secțiunea dibi:

dibi:
	host: localhost

Ca extensie se poate adăuga și o clasă care are parametri:

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

Includerea fișierelor

Putem include alte fișiere de configurare în secțiunea includes:

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

Numele parameters.php nu este o greșeală de tipar, configurația poate fi scrisă și într-un fișier PHP, care o returnează ca array:

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

Dacă în fișierele de configurare apar elemente cu aceleași chei, acestea vor fi suprascrise sau, în cazul array-urilor, combinate. Fișierul inclus ulterior are prioritate mai mare decât cel anterior. Fișierul în care este specificată secțiunea includes are prioritate mai mare decât fișierele incluse în el.

Adăugarea automată a serviciilor în containerul DI face munca extrem de plăcută. Nette adaugă automat presenterii în container, dar se pot adăuga ușor și orice alte clase.

Este suficient să specificați în ce directoare (și subdirectoare) trebuie căutate clasele:

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

De obicei, însă, nu dorim să adăugăm absolut toate clasele și interfețele, așa că le putem filtra:

search:
	-	in: %appDir%/Forms

		# filtrare după numele fișierului (string|string[])
		files:
			- *Factory.php

		# filtrare după numele clasei (string|string[])
		classes:
			- *Factory

Sau putem selecta clase care moștenesc sau implementează cel puțin una dintre clasele specificate:

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

Se pot defini și reguli de excludere, adică măști pentru numele clasei sau strămoși ereditari, care, dacă se potrivesc, serviciul nu se adaugă în containerul DI:

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

Tuturor serviciilor li se pot seta tag-uri:

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

Combinare

Dacă în mai multe fișiere de configurare apar elemente cu aceleași chei, acestea vor fi suprascrise sau, în cazul array-urilor, combinate. Fișierul inclus ulterior are prioritate mai mare decât cel anterior.

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

Pentru array-uri, se poate preveni combinarea specificând un semn de exclamare după numele cheii:

config1.neon config2.neon rezultat
items:
	- 1
	- 2
items!:
	- 3
items:
	- 3
versiune: 3.x