Contenitore Nette DI
Nette DI è una delle librerie Nette più interessanti. È in grado di generare e aggiornare automaticamente contenitori DI compilati, estremamente veloci e incredibilmente facili da configurare.
I servizi che devono essere creati da un contenitore DI sono solitamente definiti tramite file di configurazione in formato NEON. Il contenitore che abbiamo creato manualmente nella sezione precedente sarebbe scritto come segue:
parameters:
db:
dsn: 'mysql:'
user: root
password: '***'
services:
- Nette\Database\Connection(%db.dsn%, %db.user%, %db.password%)
- ArticleFactory
- UserController
La notazione è davvero breve.
Tutte le dipendenze dichiarate nei costruttori delle classi ArticleFactory
e UserController
vengono
trovate e passate da Nette DI stesso grazie al cosiddetto autowiring, quindi non è necessario specificare nulla nel
file di configurazione. Quindi, anche se i parametri cambiano, non è necessario modificare nulla nella configurazione. Nette
rigenererà automaticamente il contenitore. Potete concentrarvi esclusivamente sullo sviluppo dell'applicazione.
Se si vogliono passare le dipendenze usando i setter, si può usare la sezione setup per farlo.
Nette DI genererà direttamente il codice PHP per il contenitore. Il risultato è un file .php
che si può aprire
e studiare. Questo permette di vedere esattamente come funziona il contenitore. È anche possibile eseguire il debug nell'IDE e
procedere con il codice. E soprattutto: il PHP generato è estremamente veloce.
Nette DI può anche generare codice factory basato
sull'interfaccia fornita. Pertanto, invece della classe ArticleFactory
, è sufficiente creare un'interfaccia
nell'applicazione:
interface ArticleFactory
{
function create(): Article;
}
L'esempio completo è disponibile su GitHub.
Uso autonomo
Utilizzare la libreria Nette DI in un'applicazione è molto semplice. Per prima cosa la installiamo con Composer (perché scaricare file zip è così obsoleto):
composer require nette/di
Il codice seguente crea un'istanza del contenitore DI in base alla configurazione memorizzata nel file
config.neon
:
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function ($compiler) {
$compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;
Il contenitore viene generato una sola volta, il suo codice viene scritto nella cache (la cartella
__DIR__ . '/temp'
) e alle successive richieste viene letto solo da lì.
I metodi getService()
o getByType()
sono usati per creare e recuperare i servizi. Ecco come si crea
l'oggetto UserController
:
$database = $container->getByType(UserController::class);
$database->query('...');
Durante lo sviluppo, è utile abilitare la modalità di aggiornamento automatico, in cui il contenitore viene rigenerato
automaticamente se qualsiasi classe o file di configurazione viene modificato. Basta fornire true
come secondo
parametro del costruttore ContainerLoader
.
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true);
Utilizzo con il framework Nette
Come abbiamo mostrato, l'uso di Nette DI non è limitato alle applicazioni scritte in Nette Framework: è possibile distribuirlo ovunque con sole 3 righe di codice. Tuttavia, se si sviluppano applicazioni in Nette Framework, la configurazione e la creazione del contenitore sono gestite da Bootstrap.