Qu'est-ce qu'un conteneur d'injection de dépendances pour TypeScript ?
L'injection de dépendances (DI) est un modèle de conception dans lequel un objet reçoit ses dépendances de l'extérieur, plutôt que de les créer lui-même. Un conteneur DI est un outil qui gère automatiquement la création et l'injection de ces dépendances. En TypeScript, grâce au typage statique, les conteneurs DI sont particulièrement efficaces : ils assurent la sécurité des types et simplifient les tests.
La tâche principale du conteneur est de lier les interfaces à leurs implémentations concrètes et de résoudre les chaînes de dépendances. Cela permet d'écrire un code faiblement couplé et modulaire, facile à maintenir et à étendre.
Pourquoi un conteneur DI en TypeScript ?
- Réduction du couplage du code — les classes ne dépendent pas d'implémentations concrètes, mais uniquement d'abstractions (interfaces).
- Simplification des tests — les dépendances sont facilement remplacées par des mocks ou des stubs.
- Gestion du cycle de vie — le conteneur peut créer des singletons, des objets transitoires ou des objets avec une portée définie.
- Résolution automatique des dépendances — le conteneur construit lui-même l'arbre des dépendances, évitant au développeur la construction manuelle des objets.
Conteneurs DI populaires pour TypeScript
Examinons deux bibliothèques les plus courantes : InversifyJS et TSyringe. Toutes deux prennent en charge TypeScript, mais avec des approches différentes.
1. InversifyJS
InversifyJS est un puissant conteneur IoC avec décorateurs. Il nécessite une spécification explicite des dépendances via les décorateurs @injectable() et @inject(). Convient aux grands projets avec une architecture claire.
Installation
npm install inversify reflect-metadata --saveDans le fichier tsconfig.json, assurez-vous d'inclure :
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true }}Exemple d'utilisation
import { Container, injectable, inject } from "inversify";import "reflect-metadata";
// Définir l'interface et le symbole pour la liaisoninterface ILogger { log(message: string): void;}const TYPES = { ILogger: Symbol.for("ILogger"), IUserService: Symbol.for("IUserService"),};
// Implémentation du logger@injectable()class ConsoleLogger implements ILogger { log(message: string): void { console.log(`[LOG]: ${message}`); }}
// Service dépendant du logger@injectable()class UserService { constructor(@inject(TYPES.ILogger) private logger: ILogger) {}
createUser(name: string): void { this.logger.log(`Utilisateur ${name} créé`); }}
// Configuration du conteneurconst container = new Container();container.bind<ILogger>(TYPES.ILogger).to(ConsoleLogger).inSingletonScope();container.bind<UserService>(TYPES.IUserService).to(UserService);
// Utilisationconst userService = container.get<UserService>(TYPES.IUserService);userService.createUser("Alexei");2. TSyringe
TSyringe est un conteneur DI léger de Microsoft. Il utilise des décorateurs et la résolution automatique via le constructeur. Idéal pour les projets moyens et petits.
Installation
npm install tsyringe reflect-metadata --saveLa configuration de tsconfig.json est similaire à celle d'InversifyJS.
Exemple d'utilisation
import { container, injectable, singleton } from "tsyringe";import "reflect-metadata";
// Enregistrer la classe comme singleton@singleton()class DatabaseConnection { connect(): void { console.log("Connexion à la base de données établie"); }}
// Classe avec injection automatique de dépendance@injectable()class UserRepository { constructor(private db: DatabaseConnection) {}
save(user Aussi dans la bibliothèque
Migrations de bases de données en Rust : aperçu des outils Diesel, SeaORM et sqlx
Traitement JSON en Kotlin : bibliothèques et exemples de code
Travailler avec XML en Java : DOM, SAX, StAX et JAXB — guide complet
Files d'attente de tâches pour PHP : RabbitMQ, Gearman et PhpAmqpLib
Travailler avec XML en TypeScript : bibliothèques, analyse et création de documents XML