Dependency injection
De Banane Atomic
Aller à la navigationAller à la recherche
Définition
Implémente le principe de l'Inversion of Control.
Permet de découpler les dépendances entre objets.
Les dépendances ne sont plus exprimées de manière statique dans le code mais déterminées dynamiquement à l'exécution.
The DI delegates the creation of a service that an object consumes outside of this object.
- classes are loosely coupled
- classes follow the single responsibility principle
- it becomes easier to mock the dependencies so to create unit tests
- by relying on abstractions instead of implementations, code can easily vary a given implementation
Benefits of Dependency Injection
Maintainability | classes are loosely coupled and follow the single responsibility principle |
Testability | easier to mock the dependencies so to create unit tests |
Readability | single responsibility principle |
Flexibility | easier to switch from an implementation to another |
Registration lifetimes
Registration lifetime | Description |
---|---|
Transient | create a new instance anytime its invoked |
Scoped | create a new instance for each API request |
Singleton | reate a new instance from the moment the application starts until shut down |
Exemple
Le MainViewModel veut utiliser le DataService mais ne veut pas:
- de lien statique avec la classe DataService
- prendre en charge sa construction
Dépendance entre MainViewModel et DataService
- lien statique avec la classe DataService
- prend en charge la construction de DataService
class MainViewModel { private DataService _dataService; public MainViewModel() { _dataService = new DataService(); } } |
Création d'une interface
- plus de lien statique avec la classe DataService grâce à l'interface IDataService
- prend en charge la construction de DataService
interface IDataService { } class DataService : IDataService { } class MainViewModel { private IDataService _dataService; public MainViewModel() { _dataService = new DataService(); } } |
Injection du service
- plus de lien statique avec la classe DataService grâce à l'interface IDataService
- un objet DataService est injecté dans le constructeur de MainViewModel
class MainViewModel { private IDataService _dataService; // la création du service se fait en dehors de la classe qui l'utilise public MainViewModel(IDataService dataService) { _dataService = dataService; } } |
Reduce the number of parameter in the ctor by injecting a dependency object
MyViewModel.cs |
public MyViewModel(IMyViewModelDependencies dependencies) { this.dependencies = dependencies; this.myService = dependencies.MyService; } |
IMyViewModelDependencies.cs |
internal interface IMyViewModelDependencies { IMyService MyService { get; } } |
MyViewModelDependencies.cs |
internal sealed class MyViewModelDependencies : IMyViewModelDependencies { public MyViewModelDependencies(IServiceLocator serviceLocator) { this.MyService = serviceLocator.GetInstance<IMyService>(); } public IMyService MyService { get; } } |
ServiceCollectionExtensions.cs |
internal static class ServiceCollectionExtensions { public static void AddViewModelDependencies(this IServiceCollection @this) { @this.AddTransient<IMyService, MyService>(); } } |
this.services.AddViewModelDependencies(); |