Vicode.
Couverture de Comprendre l'Injection de Dépendances dans .NET Core

Comprendre l'Injection de Dépendances dans .NET Core

2 min read·

L'Injection de Dépendances (DI - Dependency Injection) est une technique permettant d'atteindre l'Inversion de Contrôle (IoC) entre des classes et leurs dépendances. Au lieu qu'un objet ne crée lui-même ses dépendances, celles-ci lui sont fournies (injectées).

.NET Core est livré avec un fournisseur DI natif très performant et facile à utiliser. Voyons comment cela fonctionne.

Les durées de vie des services (Lifetimes)

Lorsque vous enregistrez un service dans le conteneur DI intégré, vous devez définir sa durée de vie (lifetime). Il y a trois choix possibles :

Transient (Éphémère)

Les services ayant une durée de vie Transient sont créés à chaque fois qu'ils sont demandés au conteneur de services. Cette durée de vie convient parfaitement aux services légers et sans état.

builder.Services.AddTransient<IOperationTransient, DefaultOperation>();

Scoped (Portée)

Les services ayant une durée de vie Scoped sont créés une seule fois par requête client (connexion). Lors de la création d'applications web dans ASP.NET Core, un scope est généralement créé pour chaque requête HTTP.

builder.Services.AddScoped<IOperationScoped, DefaultOperation>();

Note : C'est la durée de vie la plus courante pour les services qui interagissent avec une base de données via Entity Framework Core.

Singleton

Les services de type Singleton sont créés lors de la toute première requête (ou dès leur initialisation dans Program.cs si vous les instanciez vous-même). Chaque requête ultérieure utilise exactement la même instance de l'objet.

builder.Services.AddSingleton<IOperationSingleton, DefaultOperation>();

Injecter des dépendances

Le moyen le plus courant d'injecter une dépendance est l'injection par constructeur. Le conteneur DI se charge de résoudre et fournir les dépendances requises lors de l'instanciation de la classe.

public class OrderService
{
    private readonly IUserRepository _userRepository;
    private readonly IEmailService _emailService;

    // Le conteneur DI injecte ces interfaces
    public OrderService(IUserRepository userRepository, IEmailService emailService)
    {
        _userRepository = userRepository;
        _emailService = emailService;
    }

    public async Task CompleteOrderAsync(Guid userId)
    {
        var user = await _userRepository.GetUserAsync(userId);
        await _emailService.SendOrderConfirmationAsync(user.Email);
    }
}

En s'appuyant sur des interfaces (IUserRepository) plutôt que sur des implémentations concrètes, votre classe OrderService devient beaucoup plus facile à la tester de façon unitaire en utilisant des "Mocks" ou des "Stubs".

S'abonner à la newsletter

Recevez un e-mail à chaque fois que je publie un nouvel article sur l'ingénierie logicielle, l'architecture et .NET. Jamais de spam.