Injection de dépendances en .Net Core [ Partie 4 : Enregistrement des dépendances]
Dans la partie 3, nous avons appris le fonctionnement du Container IOC natif à .Net Core. Nous allons à présent apprendre à enregistrer nos dépendances.
Nous avons vu dans la partie 3 que tout la magie opère dans la méthode ConfigureServices, et que cette dernière prend un paramètre services de type IServiceCollection. Nous avons également vu que l’implémentation de cette interface dans la classe ServiceCollection ne contient qu’une liste de ServiceDescriptor, et quelques méthodes pour ajouter ou retirer un élément de cette liste.
Microsoft a également ajouté une classe ServiceCollectionServiceExtensions qui contient des méthodes d’extension que nous utiliserons pour enregistrer nos services. Les méthodes d’extension sont les suivantes :
- AddScoped
- AddSingleton
- AddTransient
Ces méthodes permettent d’enregistrer nos dépendances et de définir leur lifetime. Le lifetime peut ête Scoped, Singleton ou Transient.
- Transient : Une instance de la dépendance est créée à chaque fois qu’elle est injectée dans une classe.
- Singleton : Une seule instance de la dépendance est créée. C’est cette même instance qui sera injectée à chaque fois qu’elle sera demandée dans une classe.
- Scoped : Une instance de la dépendance est créée par requête client (GET, POST, PUT).
Pour comprendre la différence entre les 3, nous allons créer une interface IOperation, et ensuite 3 interfaces héritant de celle-ci : IOperationTransient, IOperationScoped et IOperationSingleton.
public interface IOperation
{
Guid OperationId { get; }
}
public interface IOperationTransient : IOperation {}
public interface IOperationScoped : IOperation {}
public interface IOperationSingleton : IOperation {}
Cette interface IOperation sera implémentée dans une classe Operation.
public class Operation : IOperation
{
public Operation() : this(Guid.NewGuid()) {}
public Operation(Guid id)
{
OperationId = id;
}
public Guid OperationId { get; private set; }
}
Nous allons à présent créer une classe OperationService dans laquelle nous injecterons nos interfaces IOperationTransient, IOperationScoped et IOperationSingleton.
public class OperationService : IOperationService
{
public OperationService(IOperationTransient operationTransient,
IOperationScoped operationScoped,
IOperationSingleton operationSingleton)
{
OperationTransient = operationTransient;
OperationScoped = operationScoped;
OperationSingleton = operationSingleton;
}
public IOperationTransient OperationTransient { get; set; }
public IOperationScoped OperationScoped { get; set; }
public IOperationSingleton OperationSingleton { get; set; }
}
Retournons maintenant dans le fichier Startup.cs pour enregistrer nos dépendances.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddTransient<IOperationTransient, Operation.Operation>();
services.AddSingleton<IOperationSingleton, Operation.Operation>();
services.AddScoped<IOperationScoped, Operation.Operation>();
services.AddTransient<IOperationService, OperationService>();
}
Nos dépendances sont à présent enregistrées dans notre Container IOC (C’est facile non?). Il ne nous reste plus qu’a créer une page web dans laquelle nous injecterons nos dépendances, et afficherons les valeurs des différents GUID.
public class IndexModel : PageModel
{
public IndexModel(
OperationService operationService,
IOperationTransient transientOperation,
IOperationScoped scopedOperation,
IOperationSingleton singletonOperation)
{
OperationService = operationService;
TransientOperation = transientOperation;
ScopedOperation = scopedOperation;
SingletonOperation = singletonOperation;
}
public OperationService OperationService { get; }
public IOperationTransient TransientOperation { get; }
public IOperationScoped ScopedOperation { get; }
public IOperationSingleton SingletonOperation { get; }
}
Les dépendances IOperationTransient, IOperationScoped et IOperationSingleton seront ainsi injectées une première fois la la page IndexModel, et une seconde fois dans OperationService. Affichons deux fois la page et voyons le résultat.

Nous pouvons constater que :
- Lorsque l’interface IOperationTransient est injectée, une nouvelle instance de la classe Operation est injectée et donc un nouveau GUID est généré.
- Lorsque l’interface IOperationSingleton est injectée, c’est toujours la même instance de la classe Operation qui est injectée, et donc un seul et unique GUID.
- Lorsque l’interface IOperationTransient est injectée, si c’est la même requête, la même instance est injectée. Lorsqu’une nouvelle requête est créée, une nouvelle instance sera créée pour cette requête. Nous avons donc un GUID commun au sein d’une même requête, mais il changera lors du rechargement de la page.
Maintenant que nous savons enregistrer nos dépendances, nous allons voir dans la prochaine partie qu’il est possible d’obtenir ou de créer d’autres extensions pour l’interface IServiceCollection.