"Fabricando" Injeções de Dependência no Angular
O Sistema de Injeção de Dependências no Angular é uma das peças chave para construirmos aplicações onde precisamos de recursos externos para os nossos componentes executarem determinadas funções.
Vamos usar como exemplo um cenário onde temos uma rota e precisamos capturar o ID de um usuário que foi passado de parâmetro. Podemos injetar o ActivatedRoute e mapearmos esse valor em forma de Observable para o componente.
Esta é uma forma muito eficiente e reativa de realizar esta tarefa! Porém vamos imaginar uma aplicação que possui dezenas de rotas e sempre precisamos fazer esta mesma tarefa. Podemos ter casos diferentes mas sempre injetamos o ActivatedRoute. Que tal "fabricarmos" uma função que faça isso para nós?
Para isso, utilizaremos um Injection Token com o Decorator Inject chamado ROUTE_ID que terá o papel de determinar sua ação no momento que injetarmos o mesmo no componente.
Agora perceba que definimos uma constante chamada ROUTE_ID_PROVIDERS no array de Providers do componente. É exatamente neste ponto onde podemos utilizar o Design Pattern Factory a partir do useFactory do Angular. A lógica de capturar o ID da rota e transformar em um Observable foi transportada para ela.
Assim o nosso componente não precisa se encarregar de executar este tipo de lógica. Ele já receberá no método construtor o valor "fabricado" pela nossa função!
Agora se precisarmos utilizar esta abordagem em outros componentes basta utilizar o mesmo Injection Token, e se for necessário, passamos uma outra função Factory no useFactory.
Vamos verificar um caso mais completo onde capturamos o ID da rota e logo em seguida chamamos um serviço para retornar um registro com base neste valor.
Tudo isso pode ser feito pelo Factory e o componente continua injetando somente o token. A diferença agora é que precisamos de duas dependências: ActivatedRoute e UserService.
Conclusão
Com esta abordagem temos as vantagens de manter as dependências mais limpas para os componentes, além de deixá-los mais escaláveis e fáceis de serem testados (Basta utilizar um Stub para o Injection Token). Temos também a possibilidade de isolar as regras em arquivos separados, facilitando a inclusão ou alteração de novos recursos.
ATUALIZAÇÃO: Função inject com o Angular 14
A versão 14 do Angular trouxe várias novidades relevantes, uma delas é a possibilidade de capturar InjectionTokens e serviços injetáveis a partir da função inject
. Você pode entender melhor no artigo que escrevi sobre as novidades da versão.
Com esse poder em mente, podemos simplificar a solução deste artigo com apenas uma função. Isso significa que não precisamos mais utilizar um InjectionToken e a utilização da função acaba sendo mais fácil. Veja abaixo como ficaria a função utilizando o inject
.
Agora no componente basta atribuir o retorno desta função para uma variável.