Interface | Injection de dépendance

Oui on peut s’imaginer une grosse seringue en lisant cet intitulé, mais non ce n’est pas ce que vous croyez même si c’est « bien trippant » 🙂

Origine SOLID

L’injection de dépendance trouve son origine dans dans un des principes SOLID qui sont représentes certaines « bonnes manières de faire » basés sur une longue expérience de programmation, d’observation et de réflexion. Ces principes sont l’oeuvres de Michael Feathers et Robert C. Martin alias Uncle Bob et s’applique pour la programmation orientée objet. L’application de ces principes pendant le développement d’un logiciel devrait favoriser la fiabilité et une robustesse comme qualité en bout de ligne. Ce qui n’est pas peu dire. L’inversion de dépendance étant le D de solid, c’est celui-là que nous verrons un peu plus en détail.

Inversion de dépendance

Ce principe s’applique pour la programmation orientée objet et sert à découpler les classes dépendantes entre elles. En inversant la dépendance, les modules en viennent à dépendre d’abstraction plutôt que de classes concrètes ou d’objet. Ça tombe bien, on peut se servir d’interface pour créer une abstraction 🙂 Voyons comment cela se concrétise.

En pratique

D’abord, l’exemple ici utilisé fait suite à l’article précédent concernant la fabrique.

Alors, dans l’article précédent, on utilisait une interface qui jouait un certain rôle et nous demandions à la fabrique de nous fabriquer un objet qui pouvait jouer le rôle pour l’accoler à l’interface. L’injection de dépendance en vient à peu près au même principe, mais nous reléguons la tâche de demander quel objet doit être utilisé pour une interface à un autre module. La classe, ou dépendance, est alors commandé et servi ailleurs et injectée dans notre objet qui doit alors utiliser cette dépendance.

Injection de dépendance par le constructeur

C’est un forme assez commune et pratique pour injecter une dépendance dans un autre classe en utilisant le constructeur de la classe.

Alors, j’ai créé une nouvelle classe ConsumerDependencyInjection qui va remplacer la classe ConsumerAvecFactory que j’ai utilisée dans l’article précédent.

Je retire le code qui fait appel à une fabrique et je place un paramètre de type IRestClient dans le constructeur qui sera passé par la suite à une variable membre restClient du même type.

Ensuite, on utilise la variable en respectant le rôle établi par l’interface IRestClient.

Voici la classe ConsumerDependencyInjection :

public class ConsumerDependencyInjection
    {
        private const string request = "http://127.0.0.1/queryThat?option=this";

        private IRestClient restClient;
        private ParameterSet _parameterSet;

        public ConsumerDependencyInjection(ParameterSet parameterSet, IRestClient restClient)
        {
            _parameterSet = parameterSet;
            InitializeComponent(restClient);
        }

        public void SendRequest()
        {
            var restRequest = new RestRequest()
            {
                Request = request
            };
            restClient.AddRestRequest(restRequest);
        }

        public HttpStatusCode HttpStatusCode { get; set; } = HttpStatusCode.BadRequest;

        public string RestClientName { get; set; }

        private void InitializeComponent(IRestClient restClient)
        {

            restClient.RestServerResponded += (sender, restEvent) =>
            {
                HttpStatusCode = restEvent.HttpStatusCode;
                RestClientName = restEvent.RestClientName;
            };
        }
}

Maintenant, pour injecter la dépendance, on peut créer l’objet qui implémente l’interface IRestClient et instancier la classe ConsumerDepencencInjection en injectant l’objet IRestClient. Dans mon exemple, j’injecte un objet de la classe RestClientFake parce que cela va nous amener vers mon prochain article qui mettra en scène des tests unitaire et des interface. Alors voici l’exemple :

public class InterfacePlay
    {
        public InterfacePlay()
        {
            InjectDependency();
        }

        private void InjectDependency()
        {
            var parameterSet = new ParameterSet();
            var restClient = new RestClientFake();
            var consumerDepInjected = new ConsumerDependencyInjection(parameterSet, restClient);
        }
}

En conclusion

L’injection de dépendance tire son origine du D des principes de programmation orientée objet SOLID. Ce principe demande d’inverser les dépendance afin que les objets dépendent plutôt d’abstractions.

En pratique, on peut dépendre d’une interface, qui est une abstraction, et injecter la dépendance dans la classe qui l’utilise par le constructeur.

Cela tend à découpler les modules et apporte une plus grande souplesse au niveau du design et la programmation.

Ce principe aide beaucoup pour tester des modules et c’est ce que nous verrons dans le prochain article.

Laisser un commentaire

Votre adresse de courriel ne sera pas publiée. Les champs obligatoires sont indiqués avec *