Container Nette DI

Nette DI é uma das mais interessantes bibliotecas Nette. Ela pode gerar e atualizar automaticamente containers DI compilados que são extremamente rápidos e incrivelmente fáceis de configurar.

Os serviços a serem criados por um contêiner DI são geralmente definidos utilizando arquivos de configuração no formato NEON. O container que criamos manualmente na seção anterior seria escrito da seguinte forma:

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

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

A notação é realmente breve.

Todas as dependências declaradas nos construtores das classes ArticleFactory e UserController são encontradas e passadas pela própria Nette DI graças à chamada autoconexão, portanto não há necessidade de especificar nada no arquivo de configuração. Portanto, mesmo que os parâmetros mudem, não há necessidade de alterar nada na configuração. A Nette irá regenerar automaticamente o recipiente. Você pode se concentrar lá puramente no desenvolvimento de aplicações.

Se você quiser passar dependências usando setters, use a seção de configuração para fazer isso.

Nette DI irá gerar diretamente o código PHP para o recipiente. O resultado é, portanto, um arquivo .php que você pode abrir e estudar. Isto permite que você veja exatamente como o contêiner funciona. Você também pode depurá-lo na IDE e passar por ela. E o mais importante: o PHP gerado é extremamente rápido.

A Nette DI também pode gerar código de fábrica com base na interface fornecida. Portanto, ao invés da classe ArticleFactory, precisamos apenas criar uma interface na aplicação:

interface ArticleFactory
{
	function create(): Article;
}

Você pode encontrar o exemplo completo no GitHub.

Uso autônomo

A utilização da biblioteca Nette DI em uma aplicação é muito fácil. Primeiro a instalamos com o Composer (porque o download de arquivos zip está tão desatualizado):

composer require nette/di

O seguinte código cria uma instância do recipiente DI de acordo com a configuração armazenada no arquivo config.neon:

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

O container é gerado apenas uma vez, seu código é escrito no cache (o diretório __DIR__ . '/temp' ) e em pedidos subsequentes é lido apenas a partir daí.

Os métodos getService() ou getByType() são usados para criar e recuperar serviços. É assim que criamos o objeto UserController:

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

Durante o desenvolvimento, é útil ativar o modo de atualização automática, onde o recipiente é automaticamente regenerado se qualquer classe ou arquivo de configuração for alterado. Basta fornecer true como segundo argumento no construtor do ContainerLoader.

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

Usando-o com a estrutura Nette

Como demonstramos, o uso de Nette DI não está limitado a aplicações escritas no Nette Framework, você pode implementá-lo em qualquer lugar com apenas 3 linhas de código. Entretanto, se você estiver desenvolvendo aplicações no Nette Framework, a configuração e a criação do container é feita pelo Bootstrap.

versão: 3.x