Contenedor Nette DI

Nette DI es una de las librerías más interesantes de Nette. Puede generar y actualizar automáticamente contenedores DI compilados que son extremadamente rápidos y sorprendentemente fáciles de configurar.

Los servicios a crear por un contenedor DI suelen definirse mediante ficheros de configuración en formato NEON. El contenedor que creamos manualmente en sección anterior se escribiría de la siguiente manera:

parameters:
	db:
		dsn: 'mysql:'
		user: root
		password: '***'

services:
	- Nette\Database\Connection(%db.dsn%, %db.user%, %db.password%)
	- ArticleFactory
	- UserController

La notación es realmente breve.

Todas las dependencias declaradas en los constructores de las clases ArticleFactory y UserController son encontradas y pasadas por el propio DI de Nette gracias al llamado autowiring, por lo que no es necesario especificar nada en el fichero de configuración. Así que incluso si los parámetros cambian, no es necesario cambiar nada en la configuración. Nette regenerará automáticamente el contenedor. Usted puede concentrarse allí puramente en el desarrollo de la aplicación.

Si quiere pasar dependencias usando setters, use la sección setup para hacerlo.

Nette DI generará directamente el código PHP para el contenedor. El resultado es un archivo .php que puede abrir y estudiar. Esto le permite ver exactamente cómo funciona el contenedor. También puede depurarlo en el IDE y recorrerlo paso a paso. Y lo más importante: el PHP generado es extremadamente rápido.

Nette DI también puede generar código de fábrica basado en la interfaz suministrada. Por lo tanto, en lugar de la clase ArticleFactory, sólo necesitamos crear una interfaz en la aplicación:

interface ArticleFactory
{
	function create(): Article;
}

Puedes encontrar el ejemplo completo en GitHub.

Uso autónomo

Utilizar la librería Nette DI en una aplicación es muy sencillo. Primero la instalamos con Composer (porque descargar archivos zip está muy pasado de moda):

composer require nette/di

El siguiente código crea una instancia del contenedor DI según la configuración almacenada en el fichero config.neon:

$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function ($compiler) {
	$compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;

El contenedor se genera sólo una vez, su código se escribe en la caché (el directorio __DIR__ . '/temp') y en las siguientes peticiones sólo se lee de ahí.

Los métodos getService() o getByType() se utilizan para crear y recuperar servicios. Así es como creamos el objeto UserController:

$database = $container->getByType(UserController::class);
$database->query('...');

Durante el desarrollo, es útil habilitar el modo auto-refresh, en el que el contenedor se regenera automáticamente si se cambia alguna clase o fichero de configuración. Simplemente proporciona true como segundo argumento en el constructor ContainerLoader.

$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true);

Usándolo con Nette Framework

Como hemos mostrado, el uso de Nette DI no está limitado a aplicaciones escritas en Nette Framework, puedes desplegarlo en cualquier lugar con sólo 3 líneas de código. Sin embargo, si estás desarrollando aplicaciones en Nette Framework, la configuración y creación del contenedor es manejada por Bootstrap.