Definições de serviço
A configuração é o local em que instruímos o contêiner DI sobre como montar serviços individuais e como conectá-los a outras dependências. O Nette oferece uma maneira muito clara e elegante de fazer isso.
A seção services
no arquivo de configuração do NEON é onde definimos nossos serviços personalizados e suas
configurações. Vamos dar uma olhada em um exemplo simples de definição de um serviço chamado database
, que
representa uma instância da classe PDO
:
Essa configuração resulta no seguinte método de fábrica no contêiner DI:
Os nomes dos serviços nos permitem fazer referência a eles em outras partes do arquivo de configuração, usando o formato
@serviceName
. Se não houver necessidade de nomear o serviço, podemos simplesmente usar um marcador:
Para recuperar um serviço do contêiner DI, podemos usar o método getService()
com o nome do serviço como
parâmetro ou o método getByType()
com o tipo de serviço:
Criação de serviços
Geralmente, criamos um serviço simplesmente instanciando uma classe específica. Por exemplo:
Se precisarmos expandir a configuração com chaves adicionais, a definição poderá ser expandida em várias linhas:
A chave create
tem um alias factory
, ambas as versões são comuns na prática. No entanto,
recomendamos o uso de create
.
Como alternativa, os argumentos do construtor ou o método de criação podem ser escritos na chave
arguments
:
Os serviços não precisam ser criados apenas pela simples instanciação de uma classe; eles também podem resultar da chamada de métodos estáticos ou métodos de outros serviços:
Observe que, para simplificar, em vez de ->
, usamos ::
, veja a expressão significa. Esses métodos de fábrica são gerados:
O contêiner DI precisa saber o tipo do serviço criado. Se criarmos um serviço usando um método que não tenha um tipo de retorno especificado, devemos mencionar explicitamente esse tipo na configuração:
Argumentos
Passamos argumentos para construtores e métodos de forma muito semelhante ao PHP comum:
Para facilitar a leitura, podemos listar os argumentos em linhas separadas. Nesse formato, o uso de vírgulas é opcional:
Você também pode nomear os argumentos, o que permite que você não se preocupe com a ordem deles:
Se quiser omitir determinados argumentos e usar seus valores padrão ou inserir um serviço por meio da conexão automática, use um sublinhado:
Os argumentos podem ser serviços, parâmetros e muito mais; consulte os meios de expressão.
Configuração
Na seção setup
, definimos os métodos que devem ser chamados ao criar o serviço.
Em PHP, isso seria parecido com:
Além das chamadas de método, você também pode passar valores para as propriedades. A adição de um elemento a uma matriz também é suportada, mas você precisa colocá-la entre aspas para evitar colidir com a sintaxe NEON:
Em PHP, isso se traduziria em:
Na configuração, você também pode chamar métodos estáticos ou métodos de outros serviços. Se você precisar passar
o serviço atual como um argumento, use @self
:
Observe que, para simplificar, em vez de ->
, usamos ::
, veja a expressão significa. Isso gera o seguinte método de fábrica:
Meios de Expressão
O Nette DI nos fornece recursos de expressão excepcionalmente ricos, o que nos permite articular quase tudo. Nos arquivos de configuração, podemos usar parâmetros:
Também podemos criar objetos, chamar métodos e funções:
Referir-se aos serviços pelo nome ou pelo tipo:
Use a sintaxe chamável de primeira classe:
Usar constantes:
As chamadas de método podem ser encadeadas, assim como no PHP. Para simplificar, em vez de ->
, usamos
::
:
Essas expressões podem ser usadas em qualquer lugar ao criar serviços, em argumentos, na seção de configuração ou em parâmetros:
Funções especiais
Nos arquivos de configuração, você pode utilizar essas funções especiais:
not()
para negação de valorbool()
,int()
,float()
,string()
para conversão de tipos sem perdastyped()
para gerar uma matriz de todos os serviços de um tipo especificadotagged()
para criar uma matriz de todos os serviços com uma determinada tag
Em comparação com o typecasting convencional em PHP, como (int)
, o lossless type casting lançará uma
exceção para valores não numéricos.
A função typed()
cria uma matriz de todos os serviços de um tipo específico (classe ou interface). Ela exclui
os serviços com o autowiring desativado. Vários tipos podem ser especificados, separados por vírgulas.
Você também pode passar automaticamente uma matriz de serviços de um tipo específico como um argumento usando o autowiring.
A função tagged()
cria uma matriz de todos os serviços com uma tag especificada. Várias tags podem ser
listadas, separadas por vírgulas.
Fiação automática
A chave autowired
permite modificar o comportamento de conexão automática de um serviço específico. Para
obter mais detalhes, consulte o capítulo Autowiring.
Serviços preguiçosos
O carregamento lento é uma técnica que atrasa a criação de um serviço até que ele seja realmente necessário. Você pode ativar a criação de serviços preguiçosos globalmente na configuração para todos os serviços de uma só vez. Para serviços individuais, esse comportamento pode ser substituído:
Quando um serviço é definido como preguiçoso, solicitá-lo ao contêiner DI retornará um objeto proxy especial. Esse proxy parece e se comporta como o serviço real, mas a inicialização real (chamada do construtor e configuração) ocorrerá somente na primeira invocação de qualquer um de seus métodos ou propriedades.
O carregamento lento só pode ser usado para classes definidas pelo usuário, não para classes internas do PHP. Ele requer o PHP 8.4 ou mais recente.
Tags
As tags são usadas para adicionar informações suplementares aos serviços. Você pode atribuir uma ou mais tags a um serviço:
As tags também podem conter valores:
Para recuperar todos os serviços com tags específicas, você pode usar a função tagged()
:
No contêiner DI, você pode obter os nomes de todos os serviços com uma tag específica usando o método
findByTag()
:
Modo de injeção
O uso do sinalizador inject: true
ativa a passagem de dependências por meio de variáveis públicas com a
anotação inject e os métodos inject*().
Por padrão, o inject
só é ativado para apresentadores.
Modificações no serviço
O contêiner DI contém muitos serviços adicionados por extensões internas ou de usuário. Você pode modificar as definições desses serviços diretamente na configuração. Por
exemplo, você pode alterar a classe do serviço application.application
, que é convencionalmente
Nette\Application\Application
, para outra:
O sinalizador alteration
é informativo, indicando que estamos apenas modificando um serviço existente.
Também podemos complementar a configuração:
Ao substituir um serviço, talvez você queira remover argumentos, itens de configuração ou tags originais, e é aí que o
reset
se torna útil:
Se quiser remover um serviço adicionado por uma extensão, você pode fazer isso da seguinte forma: