Injection de dépendances (Dependency Injection) en C# : guide complet

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 que l'injection de dépendances en C# et pourquoi en a-t-on besoin



Dans le développement moderne en C# et .NET, l'un des principes de conception clés est Dependency Injection (DI) — l'injection de dépendances. Ce modèle permet de créer un code faiblement couplé, testable et facile à maintenir. Au lieu que la classe crée elle-même les instances des objets dont elle a besoin (couplage fort), les dépendances sont injectées de l'extérieur.



L'objectif principal de DI est la mise en œuvre du principe Inversion of Control (IoC), où le contrôle de la création des objets est transféré à un conteneur ou framework externe. Cela change radicalement l'architecture de l'application, la rendant flexible et prête aux changements.



Le problème du couplage fort (Tight Coupling)



Considérons un exemple typique sans DI :



public class OrderService{    private readonly EmailSender _emailSender;

public OrderService() { // Dépendance forte — on crée une instance d'une classe concrète _emailSender = new EmailSender(); }

public void ProcessOrder(Order order) { // Logique de traitement de la commande _emailSender.Send("Commande traitée"); }}


Ici, OrderService dépend directement de EmailSender. Si nous voulons remplacer l'envoi d'email par SMS ou par journalisation, nous devons modifier le code de OrderService. Cela viole le Open/Closed Principle et rend les tests unitaires pratiquement impossibles.



Les principales méthodes d'injection de dépendances en C#



En C#, il existe trois méthodes principales pour implémenter DI. Chacune a ses cas d'utilisation et ses particularités.



1. Injection par constructeur (Constructor Injection)



C'est la méthode la plus populaire et recommandée dans .NET. Les dépendances sont passées via les paramètres du constructeur et sont généralement stockées dans des champs privés en lecture seule (readonly).



public interface INotificationService{    void Send(string message);}

public class EmailService : INotificationService{ public void Send(string message) { Console.WriteLine($"Email envoyé : {message}"); }}

public class OrderService{ private readonly INotificationService _notificationService;

// La dépendance est injectée via le constructeur public OrderService(INotificationService notificationService) { _notificationService = notificationService; }

public void ProcessOrder(Order order) { // Logique... _notificationService.Send("Commande traitée"); }}


Avantages : on voit clairement de quelles dépendances la classe a besoin ; les dépendances sont immuables après la création de l'objet ; facile à tester en utilisant des objets mock.



2. Injection par propriété (Property Injection)



La dépendance est définie via une propriété publique (setter). Utilisée moins souvent, lorsque la dépendance n'est pas obligatoire pour le fonctionnement de la classe.



public class OrderService{    public INotificationService NotificationService { get; set; }

public OrderService() { }

public void ProcessOrder(Order order) { if (NotificationService != null) { NotificationService.Send("Commande traitée"); } }}


Inconvénient : on peut oublier de définir la dépendance, ce qui entraînera une NullReferenceException à l'exécution. Il est recommandé de l'utiliser uniquement pour les dépendances optionnelles.



3. Injection par méthode (Method Injection)



La dépendance est passée directement dans la méthode où elle est utilisée. C'est pratique lorsque la dépendance n'est nécessaire que pour une action spécifique.



public class OrderService{    public void ProcessOrder(Order order, INotificationService notificationService)    {        // Logique...        notificat                

Blogs

Book Recommendations