Contêiner de DI do Nette

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

A forma dos serviços que o Contêiner de DI deve criar é geralmente definida usando arquivos de configuração no formato NEON. O contêiner que criamos manualmente no capítulo anterior seria escrito assim:

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

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

A notação é realmente concisa.

Todas as dependências declaradas nos construtores das classes ArticleFactory e UserController são descobertas e passadas automaticamente pelo Nette DI graças ao chamado autowiring, portanto, não é necessário especificar nada no arquivo de configuração. Assim, mesmo que os parâmetros mudem, você não precisa alterar nada na configuração. O contêiner Nette é regenerado automaticamente. Você pode se concentrar puramente no desenvolvimento da aplicação.

Se quisermos passar dependências usando setters, usamos a seção setup para isso.

Nette DI gera diretamente o código PHP do contêiner. O resultado é, portanto, um arquivo .php que você pode abrir e estudar. Graças a isso, você vê exatamente como o contêiner funciona. Você também pode depurá-lo no IDE e percorrer passo a passo. E o mais importante: o PHP gerado é extremamente rápido.

Nette DI também pode gerar código para fábricas com base na interface fornecida. Portanto, em vez da classe ArticleFactory, basta criar apenas uma interface na aplicação:

interface ArticleFactory
{
	function create(): Article;
}

Você pode encontrar o exemplo completo no GitHub.

Uso independente

Implantar a biblioteca Nette DI em uma aplicação é muito fácil. Primeiro, instalamos com o Composer (porque baixar zips é tããão ultrapassado):

composer require nette/di

O código a seguir cria uma instância do Contêiner de 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 contêiner é gerado apenas uma vez, seu código é escrito no cache (diretório __DIR__ . '/temp') e nas requisições subsequentes ele é apenas carregado de lá.

Para criar e obter serviços, são usados os métodos getService() ou getByType(). Assim 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 contêiner é automaticamente regenerado se qualquer classe ou arquivo de configuração for alterado. Basta especificar true como segundo argumento no construtor ContainerLoader.

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

Uso com o framework Nette

Como mostramos, o uso do Nette DI não se limita a aplicações escritas no Nette Framework, você pode implantá-lo em qualquer lugar com apenas 3 linhas de código. No entanto, se você desenvolve aplicações no Nette Framework, a configuração e criação do contêiner são de responsabilidade do Bootstrap.

versão: 3.x