Appearance
Les termes de l'injection de dépendance
Dependency Injection (DI)
Définition : C’est un mécanisme qui permet à Angular de créer et fournir automatiquement les objets (services, valeurs, etc.) dont tes composants ou classes ont besoin.
Image mentale : 💡 Plutôt que de “cuisiner” toi-même ton service dans chaque composant, tu le fais livrer par Angular, qui agit comme un “serveur d’objets”.
Exemple :
ts
@Component({...})
export class UserComponent {
private logger = inject(LoggerService); // Angular fournit le LoggerService
}
Injector (Injecteur)
Définition : Un injecteur est un objet Angular qui sait comment créer et fournir des dépendances.
Image mentale : 🧃 C’est comme une distributeur automatique : tu lui demandes un service, il te donne une instance.
Types principaux :
ElementInjector
→ lié à l’arbre des composants (DOM)EnvironmentInjector
→ lié à l’arbre des routes et de l’application
Exemple :
ts
const logger = inject(LoggerService);
➡️ Ici, Angular demande au bon injecteur de fournir un LoggerService
.
Token
Définition : Un token est une clé d’identification qui dit à Angular quelle dépendance tu veux. C’est ce que tu passes à inject()
ou au constructeur.
Image mentale : 🔑 C’est la “clé” que tu insères dans le distributeur (injecteur) pour obtenir le bon objet.
Types de tokens :
Une classe (souvent un service) :
tsinject(LoggerService);
Un InjectionToken (pour une valeur, une interface, une constante) :
tsexport const API_URL = new InjectionToken<string>('API_URL'); inject(API_URL);
Exemple :
ts
{ provide: API_URL, useValue: 'https://api.example.com' }
Provider
Définition : Un provider indique comment obtenir ou créer une valeur pour un token.
Image mentale : 🧰 C’est la “recette” que l’injecteur suit pour savoir comment produire le service.
Types de providers :
Type | Description | Exemple |
---|---|---|
useClass | Crée une instance d’une classe | { provide: Token, useClass: MyService } |
useValue | Fournit une valeur simple | { provide: TOKEN, useValue: 42 } |
useExisting | Alias vers un autre provider | { provide: NewToken, useExisting: OldToken } |
useFactory | Appelle une fonction qui retourne la valeur | { provide: TOKEN, useFactory: () => new Service() } |
Exemple :
ts
providers: [
{ provide: LoggerService, useClass: LoggerService },
{ provide: API_URL, useValue: 'https://api.example.com' }
]
InjectionToken
Définition : Un objet spécial utilisé comme token pour des valeurs non classes (objets, chaînes, configs…).
Image mentale : 🔖 Un “étiquette” typée que tu crées pour qu’Angular sache quoi fournir.
Exemple :
ts
export const CONFIG = new InjectionToken<AppConfig>('CONFIG');
providers: [
{ provide: CONFIG, useValue: { apiUrl: 'https://api.example.com' } }
];
Puis :
ts
const config = inject(CONFIG);
Service
Définition : Une classe que tu veux partager et réutiliser dans ton app (souvent marquée @Injectable()
).
Image mentale : 💼 Un “outil” ou une “boîte à fonctions” qu’Angular crée et partage selon ton besoin.
Exemple :
ts
@Injectable({ providedIn: 'root' })
export class LoggerService {
log(msg: string) { console.log(msg); }
}
Inject()
Définition : Une fonction moderne (depuis Angular 14) qui demande un service à l’injecteur courant.
Image mentale : 🎯 C’est comme tendre la main et dire “Donne-moi ce service”.
Exemple simple :
ts
const logger = inject(LoggerService);
Avec options avancées :
ts
const logger = inject(LoggerService, { optional: true, self: true });
ElementInjector
Définition : Un injecteur associé à chaque composant ou directive dans le DOM. Il gère les providers déclarés localement (providers: [...]
dans le décorateur).
Image mentale : 🧩 Chaque composant a sa “mini boîte à services”.
Exemple :
ts
@Component({
selector: 'app-child',
providers: [LoggerService]
})
export class ChildComponent {
private logger = inject(LoggerService); // vient de ce composant
}
EnvironmentInjector
Définition : Un injecteur “global” lié à l’application et aux routes. Il contient les services fournis dans :
ApplicationConfig.providers
Route.providers
- ou via
providedIn: 'root'
Image mentale : 🌐 C’est la “boîte à services” partagée par toute une partie de ton app (ou toute l’app).
Exemple :
ts
bootstrapApplication(AppComponent, {
providers: [
provideRouter(routes),
{ provide: LoggerService, useClass: LoggerService }
]
});
Hierarchical Injectors
Définition : C’est la manière dont Angular organise les injecteurs en arborescence. Les ElementInjector
sont dans l’arbre des composants, les EnvironmentInjector
dans l’arbre des routes.
Image mentale : 🌳 Angular a deux arbres qui coopèrent :
- l’arbre des composants (Element Injectors)
- l’arbre des environnements (Environment Injectors)
Angular cherche toujours du plus proche au plus haut.
Scope / Portée
Définition : La “zone de vie” d’un service — où et quand il est partagé.
Exemples :
Scope | Création | Durée de vie |
---|---|---|
Composant | providers dans le décorateur | détruit avec le composant |
Route | providers dans la route | persiste tant que la route est chargée |
Application | providedIn: 'root' | vie de l’app entière |
APP_INITIALIZER / provideAppInitializer
Définition : Une façon d’exécuter du code avant que l’application ne démarre.
Image mentale : ⏳ “Avant d’ouvrir la boutique, prépare les étagères.”
Exemple moderne (Angular 19+):
ts
provideAppInitializer(() => inject(ConfigService).load());
runInInjectionContext()
Définition : Permet d’exécuter du code dans le contexte d’un injecteur donné. C’est utile pour utiliser inject()
en dehors des composants (ex : dans des fonctions utilitaires).
Exemple :
ts
runInInjectionContext(envInjector, () => {
const service = inject(LoggerService);
service.log('Contexte d’injection manuel');
});
NullInjector
Définition : L’injecteur “vide” — c’est le dernier recours. Si aucun injecteur au-dessus n’a le service demandé → il renvoie une erreur.
Image mentale : 🚫 Le “fond du puits” : si tu arrives là, Angular te dit “Service introuvable !”.