L'Inversion de Contrôle (IoC) est un principe de conception qui consiste à déléguer la gestion du flux de contrôle et de la création des objets à un conteneur ou framework, afin de réduire le couplage entre les composants d'une application.
Couplé au principe de DI, Cela permet de réduire le couplage entre les composants d'une application, améliorant ainsi la flexibilité et la testabilité du code.
Dans la vie réelle, l'utilisation de l'application Uber illustre parfaitement le principe d'inversion de contrôle. L'application agit comme un conteneur de services.
Sans l'application Uber, c'était l'utilisateur qui contrôlait tout :
- Chercher un taxi
- Négocier le prix
- Expliquer son itinéraire et gérer le paiement
Ce qui change ? (Inversion du contrôle par l'application)
- L'utilisateur ne contrôle plus directement le processus, il fait juste une requête.
- L'application prend le contrôle et délègue les tâches aux bons services (calcul d'itinéraire, paiement, gestion des courses).
- Les chauffeurs n'ont pas besoin d’interagir directement avec l’utilisateur pour organiser la course, l'application s'en charge.
L'application inverse le contrôle en centralisant la gestion des services et en orchestrant automatiquement les interactions. Elle agit comme un conteneur IoC, responsable de l'instanciation, de la coordination et de l’exécution des services nécessaires au bon fonctionnement du système.
IoC inverse la gestion de la création des objets. Plutôt que de créer directement une instance via new
, le conteneur IoC fournit l'objet lorsqu'on en a besoin.
var client = new Client(); // couplage direct
var client = containerRegistry.Resolve<IClient>();
Ici, le conteneur IoC instancie Client
et les dépendances de Client (si présentes).
classDiagram
class IContainerRegistry {
+Register(IT, t)
+Resolve(IT)
}
class Client {
+ Nom
}
class IClient {
+ Nom
}
IContainerRegistry ..> Client : Création
IClient <|-- Client : Implémente
containerRegistry.RegisterSingleton<IClient, Client>();
Le conteneur IoC permet de définir comment les classes doivent être créées. Par exemple, RegisterSingleton garantit qu'il n'y aura qu'une seule instance d'une classe Client partagée partout dans l'application, contrairement à Register où une nouvelle instance est créée à chaque fois.
var client = containerRegistry.Resolve<IClient>();