Configurazione del container DI
Panoramica delle opzioni di configurazione del container DI di Nette.
File di configurazione
Il container DI di Nette si governa facilmente con i file di configurazione. Di norma si scrivono nel formato NEON. Consigliamo di usare editor con supporto per questo formato.
decorator: Decorator
di: Container DI
extensions: Installazione di altre estensioni DI
includes: Inclusione di file
parameters: Parametri
search: Registrazione automatica dei servizi
services: Servizi
Per scrivere una stringa che contiene il carattere %, dovete effettuare l'escape raddoppiandolo in
%%.
Parametri
Nella configurazione potete definire parametri, che si possono poi usare all'interno delle definizioni dei servizi. Questo vi permette di rendere più chiara la configurazione o di centralizzare i valori che potrebbero cambiare.
parameters:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: secret
Facciamo riferimento al parametro dsn in qualsiasi punto della configurazione con la notazione %dsn%.
I parametri si possono usare anche dentro le stringhe, come '%wwwDir%/images'.
I parametri non devono essere per forza solo stringhe o numeri: possono contenere anche array:
parameters:
mailer:
host: smtp.example.com
secure: ssl
user: franta@gmail.com
languages: [cs, en, de]
Facciamo riferimento a una chiave specifica come %mailer.user%.
Se il vostro codice (per esempio una classe) ha bisogno del valore di un parametro, passatelo alla classe. Per esempio nel costruttore. Non esiste un oggetto di configurazione globale a cui le classi possano chiedere i valori dei parametri. Sarebbe una violazione del principio della dependency injection.
Servizi
Vedi il capitolo dedicato.
Decorator
Come modificare in un colpo solo più servizi di un certo tipo? Per esempio, come chiamare un determinato metodo su tutti i presenter che ereditano da una certa classe base? A questo serve il decorator.
decorator:
# per tutti i servizi che sono istanze di questa classe o interfaccia
App\Presentation\BasePresenter:
setup:
- setProjectId(10) # chiama questo metodo
- $absoluteUrls = true # e imposta la variabile
I decorator si possono usare anche per impostare i tag o per attivare la modalità inject.
decorator:
InjectableInterface:
tags: [mytag: 1]
inject: true
DI
Impostazioni tecniche del container DI.
di:
# mostrare il DIC nella Tracy Bar?
debugger: ... # (bool) di norma per rilevamento automatico (attivo quando Tracy è presente)
# tipi di parametro a cui non applicare mai l'autowiring
excluded: ... # (string[])
# attivare la creazione pigra dei servizi?
lazy: ... # (bool) di norma false
# la classe da cui eredita il container DI
parentClass: ... # (string) di norma Nette\DI\Container
Servizi pigri
Impostare lazy: true attiva la creazione pigra (differita) dei servizi. Significa che i servizi non vengono
creati davvero nel momento in cui li si chiede al container DI, ma solo al momento del loro primo uso. Questo può accelerare
l'avvio dell'applicazione e ridurre l'uso della memoria, perché vengono creati solo i servizi effettivamente necessari a una
determinata richiesta.
Per un servizio specifico la creazione pigra si può regolare.
Gli oggetti pigri si possono usare solo per le classi definite dall'utente, non per le classi interne di PHP. Richiede PHP 8.4 o successivo.
Esportazione dei metadati
La classe del container DI contiene anche molti metadati. Potete ridurne la dimensione riducendo l'esportazione dei metadati.
di:
export:
# esportare i parametri?
parameters: false # (bool) di norma true
# esportare i tag e quali?
tags: # (string[]|bool) di norma tutti
- event.subscriber
# esportare i dati per l'autowiring e quali?
types: # (string[]|bool) di norma tutti
- Nette\Database\Connection
- Symfony\Component\Console\Application
Se non usate $container->getParameters(), potete disattivare l'esportazione dei parametri. Potete inoltre
esportare solo i tag che usate davvero per ottenere i servizi con $container->findByTag(...). Se non chiamate
affatto questo metodo, potete disattivare completamente l'esportazione dei tag con false.
Potete ridurre notevolmente i metadati per l'autowiring elencando solo le classi che chiedete
davvero con $container->getByType(). Anche qui, se non chiamate questo metodo (o lo chiamate solo nel file di bootstrap, per esempio per ottenere
Nette\Application\Application), potete disattivare completamente l'esportazione dei tipi con false.
Estensioni
Registrazione di ulteriori estensioni DI. Ecco come aggiungete, per esempio, l'estensione DI
Dibi\Bridges\Nette\DibiExtension3 con il nome dibi:
extensions:
dibi: Dibi\Bridges\Nette\DibiExtension3
La configurate poi nella sezione dibi:
dibi:
host: localhost
Come estensione potete aggiungere anche una classe con parametri:
extensions:
application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, [%appDir%], %tempDir%/cache)
Inclusione di file
Ulteriori file di configurazione si possono includere nella sezione includes:
includes:
- parameters.php
- services.neon
- presenters.neon
Il nome parameters.php non è un errore di battitura: la configurazione si può scrivere anche in un file PHP che
la restituisce come array:
<?php
return [
'database' => [
'main' => [
'dsn' => 'sqlite::memory:',
],
],
];
Se in più file di configurazione compaiono elementi con le stesse chiavi, essi verranno sovrascritti oppure, nel caso degli
array, uniti. Un file incluso più tardi ha priorità maggiore rispetto al precedente. Il file in cui è
indicata la sezione includes ha priorità maggiore rispetto ai file inclusi al suo interno.
Search
La registrazione automatica dei servizi nel container DI semplifica notevolmente lo sviluppo. Nette aggiunge automaticamente al container i presenter, ma potete aggiungervi facilmente anche qualsiasi altra classe.
Basta indicare in quali directory (e sottodirectory) cercare le classi:
search:
- in: %appDir%/Forms
- in: %appDir%/Model
Se vi serve una sola regola di ricerca, potete omettere l'elenco e scriverne le chiavi direttamente sotto
search:
search:
in: %appDir%
Di norma, però, non vogliamo aggiungere assolutamente tutte le classi e le interfacce, quindi possiamo filtrarle:
search:
- in: %appDir%/Forms
# filtraggio per nome di file (string|string[])
files:
- *Factory.php
# filtraggio per nome di classe (string|string[])
classes:
- *Factory
Oppure possiamo selezionare le classi che ereditano o implementano almeno una delle classi elencate:
search:
- in: %appDir%
extends:
- App\*Form
implements:
- App\*FormInterface
Potete definire anche regole di esclusione, con maschere di nomi di classe o di antenati. Se una classe corrisponde a una regola di esclusione, non verrà aggiunta al container DI:
search:
- in: %appDir%
exclude:
files: ...
classes: ...
extends: ...
implements: ...
A tutti i servizi registrati automaticamente si possono assegnare dei tag:
search:
- in: %appDir%
tags: ...
Oltre alle classi, la ricerca registra anche le interfacce che hanno un unico metodo create() o
get(), come factory o accessor generati. Le classi per cui nel container è già
registrato un servizio dello stesso tipo vengono saltate, così non si creano duplicati.
Unione
Se in più file di configurazione compaiono elementi con le stesse chiavi, essi verranno sovrascritti oppure, nel caso degli array, uniti. Il file incluso più tardi ha priorità maggiore rispetto al precedente.
| config1.neon | config2.neon | risultato |
|---|---|---|
|
|
|
Per gli array l'unione si può impedire aggiungendo un punto esclamativo dopo il nome della chiave:
| config1.neon | config2.neon | risultato |
|---|---|---|
|
|
|