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.