Différence entre l'injection de dépendance (DI) et l'inversion de contrôle (IOC)

117

J'ai vu beaucoup de références d'injection de dépendance (DI) et d'inversion de contrôle (IOC), mais je ne sais pas vraiment s'il y a une différence entre elles ou pas.

Je voudrais commencer à utiliser l'un d'eux ou les deux, mais je suis un peu confus quant à la façon dont ils sont différents.

moucheron
la source
L'inversion de contrôle fait généralement référence aux "conteneurs", tandis que l'injection de dépendance fait référence au modèle réel. Mais ils vont de pair. Je recommanderais de lire l'article de Martin Fowler pour avoir une idée du sujet.
Ben Hoffstein
L'injection de dépendance est une chose que vous faites, ce qui conduit à une structure de commande appelée Inversion of Control. Ils sont intrinsèquement liés.
2
DI est une forme d'IoC, j'ai donné une explication assez détaillée de DI et d'IoC dans cette réponse
2
Je dirais que DI est un cas particulier de la COI. Le contrôle traditionnel va module-> demander le module au gestionnaire de module, dans DI il est inversé au gestionnaire de module-> obtenir les dépendances demandées du module.
Rafał Dowgird le
En d'autres termes, IoC est une implémentation de l'utilisation de DI. Est-ce que j'ai bien compris?
dance2die

Réponses:

53

Définitions

L'inversion de contrôle est un paradigme de conception dans le but de réduire la connaissance des implémentations concrètes à partir du code du framework d'application et de donner un contrôle accru aux composants de votre application spécifiques à un domaine. Dans un système traditionnel conçu de haut en bas, le flux logique de l'application et la prise en compte de la dépendance vont des composants principaux, les premiers conçus aux derniers. En tant que telle, l'inversion de contrôle est un renversement presque littéral du contrôle et de la prise en compte de la dépendance dans une application.

L'injection de dépendance est un modèle utilisé pour créer des instances de classes sur lesquelles d'autres classes s'appuient sans savoir au moment de la compilation quelle implémentation sera utilisée pour fournir cette fonctionnalité.

Travailler ensemble

L'inversion de contrôle peut utiliser l'injection de dépendance car un mécanisme est nécessaire pour créer les composants fournissant la fonctionnalité spécifique. D'autres options existent et sont utilisées, par exemple des activateurs, des méthodes de fabrique, etc., mais les frameworks n'ont pas besoin de référencer ces classes d'utilitaires lorsque celles-ci peuvent accepter la ou les dépendances dont ils ont besoin.

Exemples

Un exemple de ces concepts à l'œuvre est le framework de plug-in dans Reflector . Les plug-ins ont beaucoup de contrôle sur le système même si l'application ne connaissait rien des plug-ins au moment de la compilation. Une seule méthode est appelée sur chacun de ces plug-ins, Initialize si memory serve, qui passe le contrôle au plug-in. Le cadre ne sait pas ce qu’ils vont faire, il leur permet simplement de le faire. Le contrôle a été pris à partir de l'application principale et attribué au composant effectuant le travail spécifique; inversion de contrôle.

La structure d’application permet l’accès à ses fonctionnalités via différents fournisseurs de services. Un plug-in est référencé aux fournisseurs de services lors de sa création. Ces dépendances permettent au plug-in d'ajouter ses propres éléments de menu, de modifier le mode d'affichage des fichiers, d'afficher ses propres informations dans les panneaux appropriés, etc. Étant donné que les dépendances sont transmises par interface, les implémentations peuvent changer et les modifications ne rompront pas la code tant que le contrat reste intact.

À l'époque, une méthode d'usine était utilisée pour créer les plug-ins à l'aide des informations de configuration, de la réflexion et de l'objet Activator (au moins dans .NET). Aujourd'hui, il existe des outils, MEF pour un, qui permettent un plus grand nombre d'options d'injection de dépendances, notamment la possibilité pour un framework d'application d'accepter une liste de plugins en tant que dépendance.

Sommaire

Bien que ces concepts puissent être utilisés et apportent des avantages indépendants, ils permettent d’écrire du code beaucoup plus souple, réutilisable et testable. En tant que tels, ils constituent des concepts importants dans la conception de solutions orientées objet.

Mandrin
la source
3
Non, l'IoC est un concept ancien et indépendant de DI (qui ne dépend pas d'IoC). Par exemple, prenons le framework Struts (Java): il repose fortement sur IoC, mais n’utilise pas DI.
Rogério
1
@ Rogério - Vous soulignez le fait que les deux concepts ne sont pas nécessaires. J'ai mis à jour ma réponse afin de clarifier cela, puis de décrire rapidement comment certains frameworks les utilisent ensemble pour permettre un code plus faiblement couplé.
Chuck
L'application la plus simple d'IoC serait probablement ActionListener. Au lieu de traiter le code de manière procédurale, le code de gestion d'événement est délégué à un code personnalisé. Inverser le contrôle.
Mike
0

Bon article pour comprendre CIO et DI http://martinfowler.com/articles/injection.html

CIO (Inversion de Contrôle)

CIO signifie

  1. le codage de l'interface (un composant doit dépendre de l'interface de l'autre composant et non de l'impl), et par exemple

    interface iComp_2 {...}
    
    class Comp_1 {
        iComp_2 c2 = ….;
    }
    
  2. supprimer le code spécifique à l'implémentation du composant, par exemple

    Comp_1 {
        iComp_2 c2 = getComp_2_Impl(); // not new Comp_2_Impl();
    }
    

La COI peut être réalisée de l’une des manières suivantes:

1. DI (Injection de dépendance)

3 types of DI

1.1 Constructor Injection

1.2 Setter Injection

1.3 Interface Injection

2. Localisateur de service

Conteneur DI (Dependency Injection)

Détermination de l'implémentation à l'exécution et non du temps de compilation: détermine au moment de l'exécution quelle implémentation concrète d'une interface à utiliser en fonction d'un fichier de configuration (donc, au moment de la compilation, nous ne savons pas quel impl va être utilisé, ce qui augmente la configurabilité de l'application) . Il s’agit d’une implémentation dans laquelle la relation concrète entre différents modules est décidée au moment de l’exécution.

Instanciation d'impl après l'injection de dépendance: après avoir déterminé l'impl, il instancie cet impl en créant d'abord toutes ses dépendances (spécifiées dans le fichier de configuration), puis en injectant ces dépendances dans l'impl

Instance Gestion du cycle de vie: les conteneurs DI conservent généralement uniquement une référence aux objets dont ils ont besoin pour gérer les cycles de vie, ou qui sont réutilisés pour les injections futures, tels que les singletons ou les poids volants. Lorsqu'il est configuré pour créer de nouvelles instances de certains composants pour chaque appel au conteneur, ce dernier oublie généralement tout simplement l'objet créé. Sinon, le ramasse-miettes aurait du mal à collecter tous ces objets lorsqu'il ne serait plus utilisé.

Yatendra Goel
la source
6
Avez-vous vraiment lu l'article sur "l'injection"? CIO ne veut pas dire ce que cette réponse dit, pas du tout.
Rogério
-3

Je dirais que "Inversion of Control" est un moyen de concevoir un système où tous les modules sont conçus comme des entités abstraites.

Et, "Injection de dépendance" est une implémentation dans laquelle la relation concrète entre différents modules est décidée au moment de l'exécution.

mB.
la source
-4

L'inversion de contrôle est un concept général, dans les langages fonctionnels, on utilise généralement des continuations. Cela vous permet d'écrire une API dans laquelle les deux côtés sont "appelants", et "l'appelé". Dans d'autres environnements, plus statiques, vous n'avez pas cette facillity, vous avez donc besoin de ce bidouillage pour insérer des indices dans le flux de contrôle.

Javier
la source