Aula 18 - Injeção de Dependências Avançada e Scopes 💉
Objetivo Pedagógico
Objetivo: Domínio do sistema de Injeção de Dependências (DI) hierárquica do Angular, provedores customizados, função inject() e resolução de scopes.
📑 1. Fundamentos Teóricos & Análise Técnica
O sistema de Injeção de Dependências (DI) do Angular é uma das mais avançadas implementações do princípio de Inversão de Controle (IoC) no desenvolvimento frontend. Diferente de frameworks que utilizam escopos globais simples, o Angular implementa um sistema de Injetores Hierárquicos, permitindo que dependências sejam isoladas por módulo, rota ou instância de componente.
A hierarquia de injetores é estruturada em duas árvores paralelas: 1. Árvore de Injetores de Ambiente (EnvironmentInjector): Provê serviços globais (providedIn: 'root') ou restritos a rotas específicas com providers: [...] no roteador. 2. Árvore de Injetores de Elementos (ElementInjector): Criada implicitamente para cada componente ou diretiva com a propriedade providers: [...] ou viewProviders: [...].
Com a introdução da função inject(), o Angular permite a injeção funcional em construtores, funções utilitárias ou inicializadores de propriedades, eliminando o acoplamento de parâmetros repetitivos no constructor de classes que herdam de classes base.
📐 Arquitetura Conceitual & Diagrama de Fluxo
graph TD
Root["Root Injector (providedIn: 'root')<br>Singletons Globais (Auth, HTTP)"] --> Route["Route Injector (Rota /dashboard)<br>Instâncias Escopadas à Rota"]
Route --> CompParent["Element Injector (DashboardComponent)<br>Serviço de Estado do Dashboard"]
CompParent --> CompChild["Element Injector (WidgetComponent)<br>Configurações Locais do Widget"]
style Root fill:#e3f2fd,stroke:#1565c0
style Route fill:#fff3e0,stroke:#e65100
style CompParent fill:#e8f5e9,stroke:#2e7d32
style CompChild fill:#f3e5f5,stroke:#7b1fa2 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Função Funcional inject(): Substituição moderna da injeção via construtor, permitindo composição funcional de lógica. - Modificadores de Resolução: Controle fino da busca de instâncias via @Optional(), @Self(), @SkipSelf() e @Host(). - Tokens de Injeção (InjectionToken): Injeção tipada de valores primitivos, configurações e interfaces abstratas. - Tree-shakable Providers: Serviços declarados com providedIn: 'root' são removidos do bundle final se não forem referenciados.
🛠️ 2. Implementação Prática em Angular Dependency Injection
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// auth.service.ts (DI Funcional e InjectionToken)
import { Injectable, InjectionToken, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
export interface AppApiConfig {
baseUrl: string;
timeoutMs: number;
}
export const API_CONFIG = new InjectionToken<AppApiConfig>('API_CONFIG', {
providedIn: 'root',
factory: () => ({ baseUrl: 'https://api.empresa.com/v1', timeoutMs: 5000 })
});
@Injectable({ providedIn: 'root' })
export class AuthService {
// Injeção funcional com a função inject()
private readonly http = inject(HttpClient);
private readonly config = inject(API_CONFIG);
getProfile() {
return this.http.get(`${this.config.baseUrl}/auth/me`);
}
}
💡 Análise Passo a Passo do Código
- Criação do Token:
new InjectionToken<AppApiConfig>cria uma chave tipada e segura para injetar objetos literais. - Uso da Função inject():
inject(HttpClient)obtém a dependência sem necessidade de declarar parâmetros verbosos no construtor. - Escopo Root Garantido:
providedIn: 'root'assegura uma única instância singleton compartilhada por toda a aplicação.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto