ASP .NET Core MVC – Inversion de contrôle et injection de dépendance

Introduction
Certaines personnes pensent que l’inversion de contrôle et l’injection de dépendance sont « similaires » dans le sens où l’injection de dépendance est l’implémentation de l’inversion de contrôle. Ceci est vrai mais un peu réducteur. Dans cet article, je vais présenter et définir ces deux concepts de la manière la plus simple possible.

L’inversion de contrôle (IoC)
Pourquoi les termes « inversion » et « contrôles » ? Le flux de contrôle d’un programme représente une vue graphique de son flux logique. Pendant longtemps, les développeurs ont maîtrisé le flux de contrôle dans les algorithmes. Avec l’inversion de contrôle le flux de contrôle est inversé, dans le sens où les développeurs ne maîtrisent plus le flux de contrôle dans son intégralité, mais des « acteurs » externes au programme tels que des services, interviennent et le modifient.
D’un point de vue ingénierie logicielle, l’inversion de contrôle est un modèle de conception générique qui consiste à réduire voire supprimer les dépendances entre deux classes. On parle alors de « couplage faible » entre deux classes. Dans quel but ? Améliorer fortement la maintenance corrective et évolutive des logiciels, afin de limiter la propagation de modifications dans leur code.
Ce modèle de conception peut être implémenté de manières différentes : les évènements, les délégués, les injections de dépendance, …

L’injection de dépendance
L’injection de dépendance est une implémentation de l’inversion de contrôle. Des objets sont injectés dans des algorithmes, sans que ces algorithmes ne sachent comment ces objets ont été créés, ni leur durée de vie. La dépendance est donc prise en charge par un élément externe au logiciel.
Ces objets peuvent être fournis de différentes manières et provenir de différentes sources de données. Par exemple, dans ASP .NET Core MVC qui prend en charge de manière native les injections de dépendance, les objets sont fournis dans un « conteneur IoC » et sont injectés dans des traitements au travers d’interface par un service proposé par le framework ASP .NET Core. Le développeur alimente le conteneur IoC en ajoutant des instructions dans la méthode ConfigureServices de la classe Startup.
Voici un exemple :

  • La classe Formation définit pour chaque formation un libellé :
public class Formation
{
    public string _Libelle { get; set; }

    public Formation(string aLibelle)
    {
        this.Libelle = aLibelle;
    }
}
  • L’interface IFormation permet de renforcer le couplage faible en instaurant une notion de contrat avec les classes qui vont utiliser les objets au travers des injections de dépendance :
public interface IFormationService
{
    List<Formation> ListeFormations { get; set; }
}
  • Voici la classe implémentant cette interface :
public class FormationService : IFormationService
{
    public List<Formation> ListeFormations { get; set; }

    public FormationService()
    {
        this.ListeFormations = new List<Formation>()
        {
            new Formation("C#"),
            new Formation("VB"),
            new Formation("ASP"),
            new Formation(DateTime.Now.ToString())
        };
    }
}
  • Enregistrement de la dépendance de service :
public void ConfigureServices(IServiceCollection services)
{
    //services.AddTransient<IFormationService, FormationService>();
    //services.AddScoped<IFormationService, FormationService>();
    services.AddSingleton<IFormationService, FormationService>();

    services.AddMvc();
}
  • Et enfin le Framework ASP .NET Core MVC injecte une instance de la classe FormationService au travers de l’interface IFormationService dans le constructeur d’un contrôleur :
public class HomeController : Controller
{
    private IFormationService FormationService { get; }

    public HomeController(IFormationService aFormationService)
    {
        this.FormationService = aFormationService;
    }

    public IActionResult Index()
    {
        return View(this.FormationService.ListeFormations);
    }
}

About: James RAVAILLE

Travaillant avec la plateforme Microsoft .NET depuis 2002, j’alterne les missions de formation et d’ingénierie avec cette plateforme. J’écris ce blog pour transmettre mes connaissances à tout développeur, qu’il soit débutant ou expérimenté.