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 that their injection into a class is required
Scoped equivalent to the lifetime of the HTTP request
Singleton from the moment the application starts until it shuts 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
Csharp.svg
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
Csharp.svg
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
Csharp.svg
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>();
    }
}
Cs.svg
this.services.AddViewModelDependencies();

IoC frameworks