Inversify TypeScript : guide complet avec exemples pratiques

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Qu'est-ce qu'Inversify et pourquoi l'utiliser ?

Inversify est un conteneur IoC (Inversion of Control) puissant et léger pour TypeScript et JavaScript. Il implémente le pattern Dependency Injection (DI), l'un des principes fondamentaux du SOLID. Inversify permet de gérer les dépendances entre les classes, rendant le code plus modulaire, testable et maintenable.

Pourquoi en avez-vous besoin ? En programmation traditionnelle, les classes créent elles-mêmes leurs dépendances (par exemple avec new). Cela entraîne un fort couplage du code. Inversify inverse ce processus : les dépendances sont "injectées" de l'extérieur (d'où le nom Inversion of Control). Le conteneur se charge de la création et de la gestion du cycle de vie des objets.

Les principaux avantages d'Inversify :

  • Faible couplage : Les classes dépendent d'abstractions (interfaces), pas d'implémentations concrètes.
  • Tests facilités : Remplacez facilement les dépendances réelles par des mocks/stubs dans vos tests.
  • Gestion du cycle de vie : Le conteneur peut créer des objets en tant que singletons ou de nouvelles instances à chaque appel.
  • Lisibilité et maintenabilité : Toutes les dépendances sont déclarées explicitement et faciles à tracer.
  • Évolutivité : Idéal pour les grands projets avec de nombreux modules.

Installation d'Inversify

Inversify s'installe via npm. Pour travailler avec TypeScript, vous aurez également besoin d'installer reflect-metadata (bibliothèque pour les décorateurs) et de configurer tsconfig.json.

# Installation d'Inversify et reflect-metadata
npm install inversify reflect-metadata --save

# Installation des types TypeScript (si non installés)
npm install @types/node --save-dev

Configuration de tsconfig.json :

{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "types": ["reflect-metadata"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Important : Les décorateurs @injectable() et @inject() fonctionnent uniquement si experimentalDecorators et emitDecoratorMetadata sont activés.

Démarrage rapide avec un exemple de code

Créons un exemple simple : un service d'envoi de notifications. Nous aurons une interface INotificationService, son implémentation EmailNotificationService et une classe UserService qui utilise ce service.

// 1. Import des modules nécessaires
import "reflect-metadata";
import { Container, injectable, inject } from "inversify";

// 2. Définition de l'interface (abstraction)
interface INotificationService {
  send(message: string): void;
}

// 3. Implémentation de l'interface
@injectable()
class EmailNotificationService implements INotificationService {
  send(message: string): void {
    console.log(`Envoi d'email : ${message}`);
  }
}

// 4. Classe dépendant de INotificationService
@injectable()
class UserService {
  private notificationService: INotificationService;

  constructor(
    @inject("INotificationService") notificationService: INotificationService
  ) {
    this.notificationService = notificationService;
  }

  notifyUser(userId: string): void {
    this.notificationService.send(`Notification pour l'utilisateur ${userId}`);
  }
}

// 5. Création du conteneur et enregistrement des dépendances
const container = new Container();
container.bind("INotificationService").to(EmailNotificationService);
container.bind(                    

Recommendations