Le design pattern Dependency Injection (DI) est une technique de conception dans laquelle les dépendances d'un objet sont injectées plutôt que créées à l'intérieur de cet objet. L'objectif est de rendre un objet indépendant des détails de l'implémentation de ses dépendances, ce qui améliore la modularité, la testabilité et la réutilisabilité du code.
En C#, l'injection de dépendances est souvent mise en œuvre en utilisant des frameworks d'injection de dépendances tels que ASP.NET Core DI, Ninject, Unity, etc., ou même manuellement en passant les dépendances via les constructeurs, propriétés ou méthodes.
Voici un exemple simple d'injection de dépendances en C# sans utiliser de framework externe :
```csharp
using System;
// Interface représentant une dépendance
public interface ILogger
{
void Log(string message);
}
// Implémentation concrète de la dépendance
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine($"[Console Logger] {message}");
}
}
// Classe utilisant l'injection de dépendances
public class OrderProcessor
{
private readonly ILogger logger;
// Injection de dépendance via le constructeur
public OrderProcessor(ILogger logger)
{
this.logger = logger;
}
public void ProcessOrder(string orderInfo)
{
// Logique métier de traitement de la commande
logger.Log($"Processing order: {orderInfo}");
}
}
class Program
{
static void Main()
{
// Configuration et injection des dépendances manuellement
ILogger consoleLogger = new ConsoleLogger();
OrderProcessor orderProcessor = new OrderProcessor(consoleLogger);
// Utilisation de la classe avec les dépendances injectées
orderProcessor.ProcessOrder("12345");
}
}
```
Dans cet exemple, `OrderProcessor` dépend de `ILogger`, mais au lieu de créer directement une instance de `ConsoleLogger` à l'intérieur de `OrderProcessor`, nous passons l'instance requise via le constructeur. Cela permet de remplacer facilement l'implémentation de `ILogger` sans modifier `OrderProcessor`, ce qui rend le code plus souple et facile à tester.
============== Dependency Injection =================
L'injection de dépendances (Dependency Injection, ou DI) est une technique utilisée pour rendre vos applications C# plus modulaires et testables en séparant la création des objets de leur utilisation. Cette approche repose souvent sur un conteneur d'inversion de contrôle (IoC) pour gérer les dépendances automatiquement.
1. Frameworks pour l'injection de dépendances
En C#, plusieurs frameworks prennent en charge l'injection de dépendances. Les plus courants sont :
1.1 Microsoft.Extensions.DependencyInjection
- Framework natif de .NET (disponible dans .NET Core et .NET 5+).
- Léger, simple à configurer.
- Souvent utilisé avec ASP.NET Core.
1.2 Autres frameworks populaires
- Autofac : plus riche en fonctionnalités (cycles de vie complexes, modularité).
- Ninject : facile à utiliser, bien que plus lourd.
- Castle Windsor : adapté aux projets complexes nécessitant des conteneurs puissants.
- Unity : utilisé historiquement, mais moins populaire aujourd'hui.
Pour débuter ou pour des projets .NET modernes, Microsoft.Extensions.DependencyInjection est recommandé.
2. Principes de base de l'injection de dépendances
2.1 Types d'injection :
-
Injection par constructeur (recommandée)
Les dépendances sont passées dans le constructeur de la classe. -
Injection par propriété
Les dépendances sont affectées via des propriétés publiques. -
Injection par méthode
Les dépendances sont fournies à une méthode spécifique lors de l'appel.
3. Exemple avec Microsoft.Extensions.DependencyInjection
Étape 1 : Configuration du conteneur DI
Commencez par ajouter le package :
dotnet add package Microsoft.Extensions.DependencyInjection
Ensuite, configurez vos services :
using Microsoft.Extensions.DependencyInjection;
using System;
public interface IMessageService
{
void SendMessage(string message);
}
public class EmailService : IMessageService
{
public void SendMessage(string message)
{
Console.WriteLine($"Email sent: {message}");
}
}
class Program
{
static void Main(string[] args)
{
// 1. Créer un conteneur DI
var services = new ServiceCollection();
// 2. Enregistrer des services dans le conteneur
services.AddTransient<IMessageService, EmailService>(); // Liaison interface/implémentation
// 3. Construire le conteneur
var serviceProvider = services.BuildServiceProvider();
// 4. Résoudre et utiliser le service
var messageService = serviceProvider.GetService<IMessageService>();
messageService.SendMessage("Hello, Dependency Injection!");
}
}
Étape 2 : Modes de durée de vie (lifetimes)
Lors de l’enregistrement d’un service, vous pouvez spécifier sa durée de vie :
AddTransient
: une nouvelle instance à chaque demande.AddScoped
: une instance par scope (utile dans ASP.NET pour une requête HTTP).AddSingleton
: une seule instance pour l'application entière.
4. Utilisation dans ASP.NET Core
ASP.NET Core intègre le conteneur DI par défaut. Voici un exemple :
Configuration dans Program.cs
var builder = WebApplication.CreateBuilder(args);
// Enregistrer des services dans le conteneur
builder.Services.AddScoped<IMessageService, EmailService>();
var app = builder.Build();
// Utiliser un service
app.MapGet("/", (IMessageService messageService) =>
{
messageService.SendMessage("Hello from ASP.NET Core!");
return Results.Ok();
});
app.Run();
5. Pourquoi utiliser un framework DI ?
- Découplage : Les classes dépendent d’interfaces, et non d’implémentations concrètes.
- Testabilité : Vous pouvez injecter des dépendances simulées (mock) dans les tests unitaires.
- Gestion centralisée des dépendances : Plus facile de contrôler la création et la durée de vie des objets.
Pour des applications modernes, Microsoft.Extensions.DependencyInjection est souvent suffisant. Si vous avez des besoins avancés (cycles complexes, modules), envisagez Autofac.
Aucun commentaire:
Enregistrer un commentaire