C# — Dependency Inversion (DIP) & Dependency Injection (DI)


1. Dependency Inversion Principle (DIP)

DIP = principe de conception (le D de SOLID).

Il dit :

❌ Exemple SANS DIP

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

public class NotificationManager
{
    private readonly EmailService _service = new EmailService(); // dépendance concrète ❌

    public void Notify(string msg)
    {
        _service.Send(msg);
    }
}

Problèmes :

✔ Exemple AVEC DIP

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

public class EmailService : INotifier
{
    public void Send(string message)
        => Console.WriteLine("Email envoyé : " + message);
}

public class NotificationManager
{
    private readonly INotifier _notifier;

    public NotificationManager(INotifier notifier)
    {
        _notifier = notifier; // dépend d'une abstraction ✔
    }

    public void Notify(string msg)
    {
        _notifier.Send(msg);
    }
}

2. Dependency Injection (DI)

DI = technique / mécanisme qui permet d’appliquer DIP en injectant les dépendances de l’extérieur.

Types d’injection :

✔ DI manuelle (simple et lisible)

INotifier notifier = new EmailService();
var manager = new NotificationManager(notifier);

manager.Notify("Hello DI !");

✔ DI via container (ex : ASP.NET Core)

services.AddTransient<INotifier, EmailService>();
services.AddTransient<NotificationManager>();

Utilisation :

var manager = provider.GetRequiredService<NotificationManager>();
manager.Notify("Hello depuis ASP.NET Core !");

3. Comment DIP & DI sont liés

DIP impose d’utiliser des abstractions (interfaces). DI permet d’injecter l’implémentation concrète dans ces abstractions.

✔ DIP = règle

“Les classes doivent dépendre d’interfaces, pas de classes concrètes.”

✔ DI = solution

“Je fournis ces interfaces automatiquement.”

4. Résumé clair

Ensemble : DIP + DI = code découplé, testable, évolutif.