Plusieurs questions ont déjà été publiées avec des questions spécifiques sur l' injection de dépendance , telles que le moment de l'utiliser et les cadres disponibles. cependant,
Qu'est-ce que l'injection de dépendance et quand / pourquoi doit-elle ou ne doit-elle pas être utilisée?
Réponses:
L'injection de dépendance transmet la dépendance à d'autres objets ou framework (injecteur de dépendance).
L'injection de dépendances facilite les tests. L'injection peut être effectuée par le constructeur .
SomeClass()
a son constructeur comme suit:Problème : Si
myObject
implique des tâches complexes telles que l'accès au disque ou l'accès au réseau, il est difficile de faire un test unitaire surSomeClass()
. Les programmeurs doivent se moquermyObject
et peuvent intercepter l'appel d'usine.Solution alternative :
myObject
en argument au constructeurmyObject
peut être passé directement, ce qui facilite les tests.Il est plus difficile d'isoler les composants dans les tests unitaires sans injection de dépendance.
En 2013, lorsque j'ai écrit cette réponse, c'était un thème majeur sur le blog de test Google . Cela reste le plus grand avantage pour moi, car les programmeurs n'ont pas toujours besoin de la flexibilité supplémentaire dans leur conception d'exécution (par exemple, pour le localisateur de services ou des modèles similaires). Les programmeurs doivent souvent isoler les classes pendant les tests.
la source
La meilleure définition que j'ai trouvée jusqu'à présent est celle de James Shore :
Il y a un article de Martin Fowler qui peut aussi s'avérer utile.
L'injection de dépendances fournit essentiellement les objets dont un objet a besoin (ses dépendances) au lieu de le faire construire lui-même. C'est une technique très utile pour les tests, car elle permet de moquer ou de bloquer les dépendances.
Les dépendances peuvent être injectées dans les objets par de nombreux moyens (comme l'injection de constructeur ou l'injection de setter). On peut même utiliser des cadres d'injection de dépendance spécialisés (par exemple Spring) pour ce faire, mais ils ne sont certainement pas nécessaires. Vous n'avez pas besoin de ces cadres pour avoir une injection de dépendance. L'instanciation et le passage d'objets (dépendances) de manière explicite est tout aussi bien une injection qu'une injection par framework.
la source
J'ai trouvé cet exemple amusant en termes de couplage lâche :
Toute application est composée de nombreux objets qui collaborent entre eux pour effectuer des tâches utiles. Traditionnellement, chaque objet est responsable d'obtenir ses propres références aux objets dépendants (dépendances) avec lesquels il collabore. Cela conduit à des classes hautement couplées et à un code difficile à tester.
Par exemple, considérons un
Car
objet.A
Car
dépend des roues, du moteur, du carburant, de la batterie, etc. pour fonctionner. Traditionnellement, nous définissons la marque de ces objets dépendants ainsi que la définition de l'Car
objet.Sans injection de dépendance (DI):
Ici, l'
Car
objet est responsable de la création des objets dépendants.Et si nous voulons changer le type de son objet dépendant - disons
Wheel
- après lesNepaliRubberWheel()
piqûres initiales ? Nous devons recréer l'objet Car avec sa nouvelle dépendanceChineseRubberWheel()
, mais seul leCar
fabricant peut le faire.Alors qu'est-ce que cela
Dependency Injection
fait pour nous ...?Lorsque vous utilisez l'injection de dépendance, les objets reçoivent leurs dépendances au moment de l'exécution plutôt qu'au moment de la compilation (temps de fabrication de la voiture) . Afin que nous puissions maintenant changer le
Wheel
moment où nous voulons. Ici, ledependency
(wheel
) peut être injectéCar
au moment de l'exécution.Après avoir utilisé l'injection de dépendance:
Ici, nous injectons les dépendances (roue et batterie) lors de l'exécution. D'où le terme: injection de dépendance.
Source: Comprendre l'injection de dépendance
la source
new
un pneu? Je ne. Tout ce que j'ai à faire, c'est de les acheter (injecter via param), d'installer et wah-lah! Donc, pour en revenir à la programmation, disons qu'un projet C # doit utiliser une bibliothèque / classe existante, il existe deux façons d'exécuter / déboguer, 1-ajouter une référence à l'ensemble du projet de celanew
elle, l'option 2 est de la transmettre en tant que param. Peut ne pas être précis, mais simple stupide facile à comprendre.L'injection de dépendance est une pratique dans laquelle les objets sont conçus de manière à recevoir des instances des objets provenant d'autres morceaux de code, au lieu de les construire en interne. Cela signifie que tout objet implémentant l'interface requise par l'objet peut être remplacé sans modifier le code, ce qui simplifie les tests et améliore le découplage.
Par exemple, considérez ces classes:
Dans cet exemple, la mise en œuvre de
PersonService::addManager
etPersonService::removeManager
aurait besoin d'une instance deGroupMembershipService
afin de faire son travail. Sans injection de dépendance, la manière traditionnelle de procéder serait d'instancier une nouvelleGroupMembershipService
dans le constructeur dePersonService
et d'utiliser cet attribut d'instance dans les deux fonctions. Cependant, si le constructeur deGroupMembershipService
a plusieurs choses dont il a besoin, ou pire encore, il y a des "setters" d'initialisation qui doivent être appelés sur leGroupMembershipService
, le code se développe assez rapidement, et lePersonService
maintenant dépend non seulement duGroupMembershipService
mais aussi de tout ce quiGroupMembershipService
dépend de. En outre, le lien avecGroupMembershipService
est codé en dur dans lePersonService
qui signifie que vous ne pouvez pas "simuler" unGroupMembershipService
à des fins de test ou pour utiliser un modèle de stratégie dans différentes parties de votre application.Avec l'injection de dépendances, au lieu d'instancier le
GroupMembershipService
dans votrePersonService
, vous devez le transmettre auPersonService
constructeur, ou bien ajouter une propriété (getter et setter) pour en définir une instance locale. Cela signifie que vous n'avezPersonService
plus à vous soucier de la façon de créer unGroupMembershipService
, il accepte simplement ceux qui lui sont donnés et fonctionne avec eux. Cela signifie également que tout ce qui est une sous-classe deGroupMembershipService
, ou implémente l'GroupMembershipService
interface, peut être "injecté" dans lePersonService
, et lePersonService
n'a pas besoin de connaître le changement.la source
La réponse acceptée est bonne - mais je voudrais ajouter à cela que DI ressemble beaucoup à l'évitement classique des constantes codées en dur dans le code.
Lorsque vous utilisez une constante comme un nom de base de données, vous la déplacez rapidement de l'intérieur du code vers un fichier de configuration et passez une variable contenant cette valeur à l'endroit où elle est nécessaire. La raison en est que ces constantes changent généralement plus fréquemment que le reste du code. Par exemple, si vous souhaitez tester le code dans une base de données de test.
DI est analogue à cela dans le monde de la programmation orientée objet. Les valeurs à la place des littéraux constants sont des objets entiers - mais la raison pour déplacer le code en les créant hors du code de classe est similaire - les objets changent plus fréquemment que le code qui les utilise. Les tests sont un cas important où un tel changement est nécessaire.
la source
Essayons un exemple simple avec les classes Car et Engine , toute voiture a besoin d'un moteur pour aller n'importe où, du moins pour l'instant. Voici donc à quoi ressemblera le code sans injection de dépendance.
Et pour instancier la classe Car, nous utiliserons le code suivant:
Le problème avec ce code que nous avons étroitement couplé à GasEngine et si nous décidons de le changer en ElectricityEngine, nous devrons réécrire la classe Car. Et plus l'application est grande, plus nous devrons ajouter de problèmes et de maux de tête et utiliser un nouveau type de moteur.
En d'autres termes, avec cette approche, notre classe Car de haut niveau dépend de la classe GasEngine de niveau inférieur qui viole le principe d'inversion de dépendance (DIP) de SOLID. DIP suggère que nous devrions dépendre d'abstractions et non de classes concrètes. Donc, pour satisfaire cela, nous introduisons l'interface IEngine et réécrivons le code comme ci-dessous:
Maintenant, notre classe Car dépend uniquement de l'interface IEngine, pas d'une implémentation spécifique du moteur. Maintenant, la seule astuce est de savoir comment créer une instance de la voiture et lui donner une classe de moteur concrète réelle comme GasEngine ou ElectricityEngine. C'est là qu'intervient l'injection de dépendance .
Ici, nous injectons (passons) essentiellement notre dépendance (instance Engine) au constructeur Car. Alors maintenant, nos classes ont un couplage lâche entre les objets et leurs dépendances, et nous pouvons facilement ajouter de nouveaux types de moteurs sans changer la classe Car.
Le principal avantage de l' injection de dépendance est que les classes sont couplées de manière plus lâche, car elles n'ont pas de dépendances codées en dur. Cela suit le principe d'inversion de dépendance, qui a été mentionné ci-dessus. Au lieu de référencer des implémentations spécifiques, les classes demandent des abstractions (généralement des interfaces ) qui leur sont fournies lors de la construction de la classe.
De plus, lorsque nous avons de nombreuses dépendances, il est très judicieux d'utiliser des conteneurs d'inversion de contrôle (IoC) qui nous permettent de savoir quelles interfaces doivent être mappées à quelles implémentations concrètes pour toutes nos dépendances et nous pouvons le faire résoudre ces dépendances pour nous lors de la construction. notre objet. Par exemple, nous pourrions spécifier dans le mappage du conteneur IoC que la dépendance IEngine doit être mappée à la classe GasEngine et lorsque nous demandons au conteneur IoC une instance de notre classe Car , il construira automatiquement notre classe Car avec une dépendance GasEngine passé.
MISE À JOUR: J'ai regardé le cours sur EF Core de Julie Lerman récemment et j'ai également aimé sa courte définition sur DI.
la source
Imaginons que vous souhaitiez aller à la pêche:
Sans injection de dépendance, vous devez vous occuper de tout vous-même. Vous devez trouver un bateau, acheter une canne à pêche, chercher des appâts, etc. C'est possible, bien sûr, mais cela vous impose beaucoup de responsabilités. En termes de logiciel, cela signifie que vous devez effectuer une recherche pour toutes ces choses.
Avec l'injection de dépendance, quelqu'un d'autre s'occupe de toute la préparation et met à votre disposition le matériel nécessaire. Vous recevrez ("être injecté") le bateau, la canne à pêche et l'appât - tous prêts à l'emploi.
la source
Voici l'explication la plus simple sur l' injection de dépendance et le conteneur d'injection de dépendance que j'ai jamais vue:
Sans injection de dépendance
Avec injection de dépendance
Utilisation d'un conteneur d'injection de dépendances
L'injection de dépendance et les conteneurs d'injection de dépendance sont des choses différentes:
Vous n'avez pas besoin d'un conteneur pour faire l'injection de dépendance. Cependant, un conteneur peut vous aider.
la source
L '«injection de dépendance» ne signifie-t-elle pas uniquement l'utilisation de constructeurs paramétrés et de setters publics?
L'article de James Shore montre les exemples suivants à titre de comparaison .
la source
new DatabaseThingie()
ne génère pas d'instance myDatabase valide.Pour rendre le concept d'injection de dépendances simple à comprendre. Prenons un exemple de bouton de commutation pour basculer (allumer / éteindre) une ampoule.
Sans injection de dépendance
Le commutateur doit savoir à l'avance à quelle ampoule je suis connecté (dépendance codée en dur). Donc,
Interrupteur -> PermanentBulb // l'interrupteur est directement connecté à l'ampoule permanente, le test n'est pas possible facilement
Avec injection de dépendance
Switch sait seulement que je dois allumer / éteindre quelle que soit l'ampoule qui m'est transmise. Donc,
Switch -> Bulb1 OU Bulb2 OU NightBulb (dépendance injectée)
Modification de l' exemple de James pour le commutateur et l'ampoule:
la source
Qu'est-ce que l'injection de dépendance (DI)?
Comme d'autres l'ont dit, l' injection de dépendance (DI) supprime la responsabilité de la création directe et de la gestion de la durée de vie d'autres instances d'objet dont dépend notre classe d'intérêt (classe de consommateurs) (au sens UML ). Ces instances sont plutôt transmises à notre classe de consommateur, généralement en tant que paramètres de constructeur ou via des paramètres de propriété (la gestion de l'instanciation de l'objet de dépendance et son passage à la classe de consommateur est généralement effectuée par un conteneur IoC (Inversion of Control) , mais c'est un autre sujet) .
DI, DIP et SOLID
Plus précisément, dans le paradigme des principes SOLID de conception orientée objet de Robert C Martin ,
DI
est l'une des implémentations possibles du principe d'inversion de dépendance (DIP) . Le DIP estD
duSOLID
mantra - autres implémentations DIP comprennent le service de localisation, et les modèles Plugin.L'objectif du DIP est de découpler les dépendances étroites et concrètes entre les classes, et au lieu de cela, de desserrer le couplage au moyen d'une abstraction, qui peut être réalisée via un
interface
,abstract class
oupure virtual class
, selon le langage et l'approche utilisés.Sans le DIP, notre code (j'ai appelé cette «classe consommatrice») est directement couplé à une dépendance concrète et est également souvent chargé de savoir comment obtenir et gérer une instance de cette dépendance, c'est-à-dire conceptuellement:
Alors qu'après l'application du DIP, l'exigence est assouplie et le souci d'obtenir et de gérer la durée de vie de la
Foo
dépendance a été supprimé:Pourquoi utiliser DIP (et DI)?
Le découplage des dépendances entre classes de cette manière permet de remplacer facilement ces classes de dépendance par d'autres implémentations qui remplissent également les conditions préalables de l'abstraction (par exemple, la dépendance peut être commutée avec une autre implémentation de la même interface). De plus, comme d'autres l'ont mentionné, la raison la plus courante pour découpler des classes via le DIP est de permettre à une classe consommatrice d'être testée isolément, car ces mêmes dépendances peuvent désormais être tronquées et / ou simulées.
Une des conséquences de DI est que la gestion de la durée de vie des instances d'objets de dépendance n'est plus contrôlée par une classe consommatrice, car l'objet de dépendance est maintenant passé dans la classe consommatrice (via l'injection de constructeur ou de setter).
Cela peut être vu de différentes manières:
Create
sur l'usine selon les besoins, et disposer de ces instances une fois terminées.Quand utiliser DI?
MyDepClass
est thread safe - que faire si nous en faisons un singleton et injectons la même instance à tous les consommateurs?)Exemple
Voici une implémentation C # simple. Étant donné la classe de consommation ci-dessous:
Bien qu'apparemment inoffensif, il a deux
static
dépendances sur deux autres classesSystem.DateTime
etSystem.Console
, ce qui limite non seulement les options de sortie de journalisation (la journalisation sur la console ne vaudra rien si personne ne regarde), mais pire, il est difficile de tester automatiquement étant donné la dépendance à une horloge système non déterministe.On peut cependant s’appliquer
DIP
à cette classe, en faisant abstraction du souci de l’horodatage comme dépendance, et enMyLogger
ne le couplant qu’à une interface simple:Nous pouvons également relâcher la dépendance à l'égard
Console
d'une abstraction, telle que aTextWriter
. L'injection de dépendance est généralement implémentée sous forme d'constructor
injection (passage d'une abstraction à une dépendance en tant que paramètre au constructeur d'une classe consommatrice) ouSetter Injection
(passage de la dépendance via unsetXyz()
setter ou une propriété .Net avec{set;}
défini). L'injection de constructeur est préférable, car cela garantit que la classe sera dans un état correct après la construction et permet aux champs de dépendance internes d'être marqués commereadonly
(C #) oufinal
(Java). Donc, en utilisant l'injection de constructeur dans l'exemple ci-dessus, cela nous laisse:(Un béton
Clock
doit être fourni, ce qui pourrait bien sûr revenirDateTime.Now
, et les deux dépendances doivent être fournies par un conteneur IoC via l'injection de constructeur)Un test unitaire automatisé peut être construit, ce qui prouve définitivement que notre enregistreur fonctionne correctement, car nous avons maintenant le contrôle sur les dépendances - le temps, et nous pouvons espionner la sortie écrite:
Prochaines étapes
L'injection de dépendances est invariablement associée à un conteneur d'inversion de contrôle (IoC) , pour injecter (fournir) les instances de dépendance concrètes et pour gérer les instances de durée de vie. Pendant le processus de configuration / amorçage, les
IoC
conteneurs permettent de définir les éléments suivants:IBar
, retourne uneConcreteBar
instance" )IDisposable
et prendront la responsabilité desDisposing
dépendances conformément à la gestion de la durée de vie configurée.En règle générale, une fois les conteneurs IoC configurés / démarrés, ils fonctionnent de manière transparente en arrière-plan, ce qui permet au codeur de se concentrer sur le code à la main plutôt que de se soucier des dépendances.
Comme dans l'exemple ci-dessus, le découplage des dépendances nécessite un certain effort de conception, et pour le développeur, il y a un changement de paradigme nécessaire pour briser l'habitude d'
new
ingérer des dépendances directement et de faire plutôt confiance au conteneur pour gérer les dépendances.Mais les avantages sont nombreux, en particulier dans la possibilité de tester minutieusement votre classe d'intérêt.
Remarque : La création / mappage / projection (via
new ..()
) de POCO / POJO / DTO de sérialisation / Graphes d'entité / Projections JSON anonymes et autres - c'est-à-dire les classes ou enregistrements "Données uniquement" - utilisés ou renvoyés par les méthodes ne sont pas considérés comme des dépendances (dans le Sens UML) et non soumis à DI. Lesnew
projeter est très bien.la source
L'intérêt de l'Injection de dépendances (DI) est de maintenir le code source de l'application propre et stable :
Pratiquement, chaque modèle de conception sépare les préoccupations pour que les modifications futures affectent les fichiers minimum.
Le domaine spécifique de DI est la délégation de la configuration et de l'initialisation des dépendances.
Exemple: DI avec script shell
Si vous travaillez occasionnellement en dehors de Java, rappelez-vous comment il
source
est souvent utilisé dans de nombreux langages de script (Shell, Tcl, etc., ou mêmeimport
en Python mal utilisé à cet effet).Considérez un
dependent.sh
script simple :Le script est dépendant: il ne s'exécutera pas correctement seul (
archive_files
n'est pas défini).Vous définissez
archive_files
dans learchive_files_zip.sh
script d'implémentation (en utilisantzip
dans ce cas):Au lieu de
source
-ing directement le script d'implémentation dans le script dépendant, vous utilisez uninjector.sh
"conteneur" qui enveloppe les deux "composants":La
archive_files
dépendance vient d'être injectée dans un script dépendant .Vous pourriez avoir injecté une dépendance qui implémente l'
archive_files
utilisation detar
ouxz
.Exemple: suppression de DI
Si le
dependent.sh
script utilisait directement les dépendances, l'approche serait appelée recherche de dépendance (qui est opposée à l' injection de dépendance ):Maintenant, le problème est que le "composant" dépendant doit effectuer lui-même l'initialisation.
Le code source du "composant" n'est ni propre ni stable car chaque changement dans l'initialisation des dépendances nécessite également une nouvelle version du fichier de code source des "composants".
Derniers mots
DI n'est pas aussi largement souligné et popularisé que dans les frameworks Java.
Mais c'est une approche générique pour diviser les préoccupations de:
L'utilisation de la configuration uniquement avec la recherche de dépendances n'aide pas car le nombre de paramètres de configuration peut changer par dépendance (par exemple, nouveau type d'authentification) ainsi que le nombre de types de dépendances pris en charge (par exemple, nouveau type de base de données).
la source
Toutes les réponses ci-dessus sont bonnes, mon objectif est d'expliquer le concept de manière simple afin que toute personne sans connaissances en programmation puisse également comprendre le concept
L'injection de dépendance est l'un des modèles de conception qui nous aident à créer des systèmes complexes de manière plus simple.
Nous pouvons voir une grande variété d'applications de ce modèle dans notre vie quotidienne. Certains des exemples sont le magnétophone, le VCD, le lecteur de CD, etc.
L'image ci-dessus est une image d'un magnétophone portable à bobine, milieu du 20e siècle. Source .
L'intention première d'un magnétophone est d'enregistrer ou de lire du son.
Lors de la conception d'un système, il faut une bobine pour enregistrer ou lire du son ou de la musique. Il existe deux possibilités pour concevoir ce système
Si nous utilisons le premier, nous devons ouvrir la machine pour changer la bobine. si nous optons pour le second, qui consiste à placer un crochet pour bobine, nous obtenons un avantage supplémentaire de jouer de la musique en changeant la bobine. et aussi de réduire la fonction uniquement à jouer quoi que ce soit dans la bobine.
Comme pour l'injection de dépendances, le processus d'externalisation des dépendances se concentre uniquement sur la fonctionnalité spécifique du composant afin que les composants indépendants puissent être couplés ensemble pour former un système complexe.
Les principaux avantages que nous avons obtenus en utilisant l'injection de dépendance.
Aujourd'hui, ce concept forme la base de cadres bien connus dans le monde de la programmation. Les Spring Angular etc sont les frameworks logiciels bien connus construits au sommet de ce concept
L'injection de dépendance est un modèle utilisé pour créer des instances d'objets sur lesquels d'autres objets s'appuient sans savoir au moment de la compilation quelle classe sera utilisée pour fournir cette fonctionnalité ou simplement la manière d'injecter des propriétés à un objet est appelée injection de dépendance.
Exemple d'injection de dépendance
Auparavant, nous écrivons du code comme celui-ci
Avec l'injection de dépendance, l'injecteur de dépendance décollera l'instanciation pour nous
Vous pouvez également lire
Différence entre l'inversion du contrôle et l'injection de dépendance
la source
Qu'est-ce que l'injection de dépendance?
L'injection de dépendance (DI) signifie découpler les objets qui dépendent les uns des autres. Supposons que l'objet A dépend de l'objet B, l'idée est donc de découpler ces objets les uns des autres. Nous n'avons pas besoin de coder en dur l'objet en utilisant un nouveau mot clé plutôt que de partager les dépendances avec les objets au moment de l'exécution malgré le temps de compilation. Si on parle de
Comment fonctionne l'injection de dépendance au printemps:
Nous n'avons pas besoin de coder en dur l'objet en utilisant un nouveau mot clé, plutôt de définir la dépendance du bean dans le fichier de configuration. Le conteneur à ressort sera chargé de tout brancher.
Inversion de contrôle (IOC)
Le CIO est un concept général et il peut être exprimé de différentes manières et l'injection de dépendance est un exemple concret du CIO.
Deux types d'injection de dépendance:
1. Injection de dépendance basée sur le constructeur:
L'ID basé sur constructeur est accompli lorsque le conteneur invoque un constructeur de classe avec un certain nombre d'arguments, chacun représentant une dépendance à l'égard d'une autre classe.
2. Injection de dépendance basée sur Setter:
L'ID basé sur Setter est accompli par le conteneur appelant des méthodes de définition sur vos beans après avoir appelé un constructeur sans argument ou une méthode d'usine statique sans argument pour instancier votre bean.
REMARQUE: il s'agit d'une bonne règle générale d'utiliser des arguments de constructeur pour les dépendances obligatoires et des paramètres pour les dépendances facultatives. Notez que si nous utilisons une annotation basée sur @Required, une annotation sur un setter peut être utilisée pour faire des setters une dépendance requise.
la source
La meilleure analogie à laquelle je peux penser est le chirurgien et ses assistants dans une salle d'opération, où le chirurgien est la personne principale et son assistant qui fournit les divers composants chirurgicaux quand il en a besoin afin que le chirurgien puisse se concentrer sur celui-ci. chose qu'il fait le mieux (chirurgie). Sans l'assistant, le chirurgien doit obtenir lui-même les composants chaque fois qu'il en a besoin.
DI pour faire court, est une technique pour supprimer une responsabilité supplémentaire commune (fardeau) sur les composants pour récupérer les composants dépendants, en les leur fournissant.
DI vous rapproche du principe de responsabilité unique (SR), comme le
surgeon who can concentrate on surgery
.Quand utiliser DI: Je recommanderais d'utiliser DI dans presque tous les projets de production (petits / grands), en particulier dans des environnements commerciaux en constante évolution :)
Pourquoi: parce que vous voulez que votre code soit facilement testable, mockable, etc. afin que vous puissiez tester rapidement vos modifications et le mettre sur le marché. En outre, pourquoi ne le feriez-vous pas lorsque vous disposez de nombreux outils / cadres gratuits impressionnants pour vous aider dans votre voyage vers une base de code où vous avez plus de contrôle.
la source
Exemple, nous avons 2 classes
Client
etService
.Client
utiliseraService
Sans injection de dépendance
Voie 1)
Voie 2)
Voie 3)
1) 2) 3) Utilisation
Les avantages
Désavantages
Client
classe de testService
constructeur, nous devons changer le code partout créer unService
objetUtiliser l'injection de dépendance
Voie 1) Injection de constructeur
En utilisant
Voie 2) Setter injection
En utilisant
Voie 3) Injection d'interface
Vérifiez https://en.wikipedia.org/wiki/Dependency_injection
===
Maintenant, ce code est déjà suivi
Dependency Injection
et il est plus facile pour laClient
classe de test .Cependant, nous utilisons encore
new Service()
beaucoup de temps et ce n'est pas bon quand on change deService
constructeur. Pour l'empêcher, nous pouvons utiliser un injecteur DI comme1) Manuel simple
Injector
En utilisant
2) Utiliser la bibliothèque: pour Android dagger2
Les avantages
Service
, il vous suffit de le modifier dans la classe InjectorConstructor Injection
, lorsque vous regardez le constructeur deClient
, vous verrez combien de dépendances deClient
classeDésavantages
Constructor Injection
, l'Service
objet est créé lors de saClient
création, parfois nous utilisons la fonction enClient
classe sans utilisationService
donc la créationService
est gaspilléeDéfinition de l'injection de dépendance
https://en.wikipedia.org/wiki/Dependency_injection
la source
Cela signifie que les objets ne devraient avoir que autant de dépendances que nécessaire pour faire leur travail et que les dépendances devraient être peu nombreuses. De plus, les dépendances d'un objet devraient être sur des interfaces et non sur des objets «concrets», lorsque cela est possible. (Un objet concret est tout objet créé avec le mot-clé new.) Le couplage lâche favorise une plus grande réutilisabilité, une facilité de maintenance plus facile et vous permet de fournir facilement des objets «fictifs» au lieu de services coûteux.
La «Dependency Injection» (DI) est également connue comme «Inversion de contrôle» (IoC), peut être utilisée comme une technique pour encourager ce couplage lâche.
Il existe deux approches principales pour mettre en œuvre l'ID:
Injection constructeur
C'est la technique de passage des dépendances d'objets à son constructeur.
Notez que le constructeur accepte une interface et non un objet concret. Notez également qu'une exception est levée si le paramètre orderDao est null. Cela souligne l'importance de recevoir une dépendance valide. L'injection de constructeur est, à mon avis, le mécanisme préféré pour donner à un objet ses dépendances. Il est clair pour le développeur lors de l'appel de l'objet quelles dépendances doivent être attribuées à l'objet "Personne" pour une exécution correcte.
Setter Injection
Mais considérons l'exemple suivant… Supposons que vous ayez une classe avec dix méthodes qui n'ont pas de dépendances, mais que vous ajoutez une nouvelle méthode qui a une dépendance sur IDAO. Vous pouvez changer le constructeur pour utiliser l'injection de constructeur, mais cela peut vous obliger à modifier tous les appels de constructeur partout. Alternativement, vous pouvez simplement ajouter un nouveau constructeur qui prend la dépendance, mais comment un développeur sait-il facilement quand utiliser un constructeur par rapport à l'autre? Enfin, si la dépendance est très coûteuse à créer, pourquoi devrait-elle être créée et transmise au constructeur alors qu'elle ne peut être utilisée que rarement? "Setter Injection" est une autre technique DI qui peut être utilisée dans des situations comme celle-ci.
Setter Injection ne force pas les dépendances à passer au constructeur. Au lieu de cela, les dépendances sont définies sur des propriétés publiques exposées par l'objet dans le besoin. Comme indiqué précédemment, les principaux facteurs de motivation pour ce faire comprennent:
Voici l'exemple à quoi ressemblerait le code ci-dessus:
la source
Je pense que puisque tout le monde a écrit pour DI, permettez-moi de poser quelques questions ..
Ceci est basé sur la réponse @Adam N publiée.
Pourquoi PersonService n'a plus à se soucier de GroupMembershipService? Vous venez de mentionner que GroupMembership a plusieurs choses (objets / propriétés) dont cela dépend. Si GMService était requis dans PService, vous l'auriez comme propriété. Vous pouvez vous moquer de cela, que vous l'ayez ou non injecté. La seule fois où j'aimerais qu'il soit injecté, c'est si GMService avait des classes enfants plus spécifiques, que vous ne sauriez pas avant l'exécution. Ensuite, vous voudriez injecter la sous-classe. Ou si vous vouliez l'utiliser comme singleton ou comme prototype. Pour être honnête, le fichier de configuration a tout codé en dur en ce qui concerne la sous-classe pour un type (interface) qu'il va injecter pendant la compilation.
ÉDITER
Un joli commentaire de Jose Maria Arranz sur DI
DI augmente la cohésion en supprimant tout besoin de déterminer le sens de la dépendance et d'écrire n'importe quel code de colle.
Faux. La direction des dépendances est sous forme XML ou sous forme d'annotations, vos dépendances sont écrites sous forme de code XML et d'annotations. XML et les annotations SONT du code source.
DI réduit le couplage en rendant tous vos composants modulaires (c'est-à-dire remplaçables) et ont des interfaces bien définies les unes aux autres.
Faux. Vous n'avez pas besoin d'un framework DI pour construire un code modulaire basé sur des interfaces.
À propos du remplaçable: avec une archive .properties très simple et Class.forName, vous pouvez définir quelles classes peuvent changer. Si N'IMPORTE QUELLE classe de votre code peut être modifiée, Java n'est pas pour vous, utilisez un langage de script. Soit dit en passant: les annotations ne peuvent pas être modifiées sans recompilation.
À mon avis, il n'y a qu'une seule raison pour les cadres DI: la réduction de la plaque de la chaudière. Avec un système d'usine bien fait, vous pouvez faire la même chose, plus contrôlé et plus prévisible que votre infrastructure DI préférée, les infrastructures DI promettent une réduction de code (XML et les annotations sont aussi du code source). Le problème est que cette réduction de la plaque de chaudière est juste réelle dans des cas très très simples (une instance par classe et similaire), parfois dans le monde réel, choisir l'objet de service approprié n'est pas aussi facile que de mapper une classe à un objet singleton.
la source
Les réponses populaires sont inutiles, car elles définissent l'injection de dépendance d'une manière qui n'est pas utile. Convenons que par «dépendance», nous entendons un autre objet préexistant dont notre objet X a besoin. Mais nous ne disons pas que nous faisons "l'injection de dépendance" quand nous disons
Nous appelons simplement cela le passage de paramètres dans le constructeur. Nous le faisons régulièrement depuis que les constructeurs ont été inventés.
"L'injection de dépendance" est considérée comme un type "d'inversion de contrôle", ce qui signifie qu'une partie de la logique est supprimée de l'appelant. Ce n'est pas le cas lorsque l'appelant passe des paramètres, donc si c'était DI, DI n'impliquerait pas une inversion de contrôle.
DI signifie qu'il existe un niveau intermédiaire entre l'appelant et le constructeur qui gère les dépendances. Un Makefile est un exemple simple d'injection de dépendances. L '"appelant" est la personne tapant "make bar" sur la ligne de commande, et le "constructeur" est le compilateur. Le Makefile spécifie que la barre dépend de foo, et il fait un
avant de faire un
La personne qui tape "make bar" n'a pas besoin de savoir que la barre dépend de foo. La dépendance a été injectée entre "make bar" et gcc.
Le but principal du niveau intermédiaire n'est pas seulement de passer les dépendances au constructeur, mais de lister toutes les dépendances en un seul endroit , et de les cacher au codeur (et non de les faire fournir au codeur).
Habituellement, le niveau intermédiaire fournit des usines pour les objets construits, qui doivent fournir un rôle que chaque type d'objet demandé doit remplir. C'est parce qu'en ayant un niveau intermédiaire qui cache les détails de la construction, vous avez déjà encouru la pénalité d'abstraction imposée par les usines, vous pourriez donc aussi bien utiliser des usines.
la source
L'injection de dépendance signifie un moyen (en fait de toute façon ) pour une partie du code (par exemple une classe) d'avoir accès aux dépendances (d'autres parties du code, par exemple d'autres classes, cela dépend) de manière modulaire sans qu'elles soient codées en dur (donc ils peuvent changer ou être remplacés librement, ou même être chargés à un autre moment, selon les besoins)
(et ps, oui c'est devenu un nom trop hype de 25 $ pour un concept assez simple) , mes
.25
centimesla source
Je sais qu'il existe déjà de nombreuses réponses, mais j'ai trouvé cela très utile: http://tutorials.jenkov.com/dependency-injection/index.html
Aucune dépendance:
Dépendance:
Remarquez comment l'
DataSourceImpl
instanciation est déplacée dans un constructeur. Le constructeur prend quatre paramètres qui sont les quatre valeurs requises par leDataSourceImpl
. Bien que laMyDao
classe dépend toujours de ces quatre valeurs, elle ne satisfait plus ces dépendances elle-même. Ils sont fournis par la classe qui crée uneMyDao
instance.la source
L'injection de dépendance est une solution possible à ce que l'on pourrait généralement appeler l'exigence d '«obscurcissement de la dépendance». L'obfuscation de la dépendance est une méthode pour retirer la nature «évidente» du processus de fourniture d'une dépendance à une classe qui l'exige et donc d'obscurcir, en quelque sorte, la fourniture de ladite dépendance à ladite classe. Ce n'est pas forcément une mauvaise chose. En fait, en obscurcissant la manière dont une dépendance est fournie à une classe, alors quelque chose en dehors de la classe est responsable de la création de la dépendance, ce qui signifie que, dans divers scénarios, une implémentation différente de la dépendance peut être fournie à la classe sans apporter de modifications. à la classe. Ceci est idéal pour basculer entre les modes de production et de test (par exemple, en utilisant une dépendance de service «factice»).
Malheureusement, la mauvaise partie est que certaines personnes ont supposé que vous aviez besoin d'un cadre spécialisé pour faire de l'obscurcissement des dépendances et que vous êtes en quelque sorte un programmeur `` moindre '' si vous choisissez de ne pas utiliser un cadre particulier pour le faire. Un autre mythe extrêmement troublant, que beaucoup croient, est que l'injection de dépendance est le seul moyen d'atteindre l'obscurcissement de la dépendance. C'est manifestement et historiquement et évidemment 100% faux, mais vous aurez du mal à convaincre certaines personnes qu'il existe des alternatives à l'injection de dépendance pour vos besoins d'obscurcissement de la dépendance.
Les programmeurs ont compris l'exigence d'obscurcissement de la dépendance depuis des années et de nombreuses solutions alternatives ont évolué avant et après la conception de l'injection de dépendance. Il existe des modèles Factory, mais il existe également de nombreuses options utilisant ThreadLocal où aucune injection dans une instance particulière n'est nécessaire - la dépendance est effectivement injectée dans le thread, ce qui a l'avantage de rendre l'objet disponible (via des méthodes getter statiques pratiques) pour toutclasse qui en a besoin sans avoir à ajouter des annotations aux classes qui en ont besoin et à mettre en place une «colle» XML complexe pour y arriver. Lorsque vos dépendances sont requises pour la persistance (JPA / JDO ou autre), cela vous permet d'atteindre la `` persistance transparente '' beaucoup plus facilement et avec des modèles de domaine et des classes de modèles commerciaux constitués uniquement de POJO (c'est-à-dire pas de framework spécifique / verrouillés dans des annotations).
la source
Extrait du livre, « Well-Grounded Java Developer: Vital techniques of Java 7 and polyglot programming
la source
Avant de passer à la description technique, visualisez-le d'abord avec un exemple réel, car vous trouverez beaucoup de choses techniques pour apprendre l'injection de dépendance, mais le temps maximum que des gens comme moi ne peuvent pas obtenir le concept de base.
Dans la première image, supposons que vous avez une usine automobile avec beaucoup d'unités. Une voiture est en fait construite dans l' unité d'assemblage mais elle a besoin de moteur , de sièges ainsi que de roues . L' unité d'assemblage dépend donc de toutes ces unités et ce sont les dépendances de l'usine.
Vous pouvez sentir que maintenant il est trop compliqué de maintenir toutes les tâches dans cette usine car avec la tâche principale (Assembler la voiture dans l'unité d'assemblage), vous devez également vous concentrer sur d' autres unités . Il est maintenant très coûteux à entretenir et le bâtiment de l'usine est immense, il vous faut donc louer votre argent supplémentaire.
Maintenant, regardez la deuxième image. Si vous trouvez des fournisseurs qui vous fourniront des roues , des sièges et des moteurs moins chers que vos coûts d'autoproduction, vous n'avez plus besoin de les fabriquer dans votre usine. Vous pouvez louer un bâtiment plus petit maintenant juste pour votre unité de montage, ce qui réduira votre tâche d'entretien et réduira vos coûts de location supplémentaires. Maintenant, vous pouvez également vous concentrer uniquement sur votre tâche principale (assemblage de voitures).
Maintenant, nous pouvons dire que toutes les dépendances pour assembler une voiture sont injectées en usine par les fournisseurs . Il s'agit d'un exemple d' injection de dépendance (DI) réelle .
Maintenant, dans le mot technique, l'injection de dépendances est une technique par laquelle un objet (ou méthode statique) fournit les dépendances d'un autre objet. Ainsi, le transfert de la tâche de créer l'objet à quelqu'un d'autre et d'utiliser directement la dépendance est appelé injection de dépendance.
Cela vous aidera maintenant à apprendre DI avec un mot technique. Cela montrera quand utiliser DI et quand ne devrait pas .
.
la source
de Book Apress.Spring.Persistence.with.Hibernate.Oct.2010
la source
L'injection de dépendance (DI) est celle de Design Patterns, qui utilise la fonction de base de la POO - la relation entre un objet et un autre objet. Alors que l'héritage hérite d'un objet pour faire un autre objet plus complexe et spécifique, la relation ou l'association crée simplement un pointeur vers un autre objet à partir d'un objet à l'aide d'un attribut. La puissance de DI est combinée avec d'autres fonctionnalités de la POO, tout comme les interfaces et le code masqué. Supposons que nous ayons un client (abonné) dans la bibliothèque, qui ne peut emprunter qu'un seul livre pour plus de simplicité.
Interface du livre:
Ensuite, nous pouvons avoir plusieurs types de livres; l'un des types est la fiction:
Désormais, l'abonné peut être associé au livre:
Les trois classes peuvent être masquées pour sa propre implémentation. Maintenant, nous pouvons utiliser ce code pour DI:
Il existe de nombreuses façons d'utiliser l'injection de dépendance. Il est possible de le combiner avec Singleton, etc., mais toujours en base ce n'est qu'une association réalisée en créant un attribut de type d'objet à l'intérieur d'un autre objet. L'utilité est seulement et seulement dans la fonctionnalité, ce code, que nous devons écrire encore et encore, est toujours préparé et fait pour nous. C'est pourquoi DI est si étroitement lié à Inversion of Control (IoC), ce qui signifie que notre programme passe le contrôle d'un autre module en cours d'exécution, qui effectue des injections de beans dans notre code. (Chaque objet, qui peut être injecté, peut être signé ou considéré comme un bean.) Par exemple, au printemps, cela se fait en créant et en initialisant ApplicationContextconteneur, qui fait ce travail pour nous. Nous créons simplement dans notre code le contexte et invoquons l'initialisation des beans. À ce moment, l'injection a été effectuée automatiquement.
la source
Injection de dépendance pour les enfants de 5 ans.
Lorsque vous sortez du réfrigérateur par vous-même, vous pouvez causer des problèmes. Vous pourriez laisser la porte ouverte, vous pourriez obtenir quelque chose que maman ou papa ne veut pas que vous ayez. Vous cherchez peut-être même quelque chose que nous n'avons même pas ou qui a expiré.
Ce que vous devriez faire, c'est énoncer un besoin: «J'ai besoin de quelque chose à boire avec le déjeuner», puis nous nous assurerons que vous avez quelque chose lorsque vous vous asseyez pour manger.
la source
Extrait de Christoffer Noring, livre de Pablo Deeleman «Learning Angular - Second Edition»:
"Au fur et à mesure que nos applications se développent et évoluent, chacune de nos entités de code nécessitera en interne des instances d'autres objets , mieux connus sous le nom de dépendances dans le monde de l'ingénierie logicielle. L' action de transmettre ces dépendances au client dépendant est appelée injection , et cela implique également la participation d'une autre entité de code, appelée l' injecteur . L' injecteur se chargera d' instancier et d' amorcer les dépendances requisesils sont donc prêts à l'emploi dès le moment où ils sont injectés avec succès dans le client. Ceci est très important car le client ne sait rien sur la façon d' instancier ses propres dépendances et ne connaît que l' interface qu'il implémente pour les utiliser. "
De: Anton Moiseev. livre "Angular Development with Typescript, Second Edition.":
«En bref, DI vous aide à écrire du code de manière peu couplée et rend votre code plus testable et réutilisable .»
la source
En termes simples, l'injection de dépendance (DI) est le moyen de supprimer les dépendances ou le couplage étroit entre différents objets. L'injection de dépendance donne un comportement cohérent à chaque objet.
DI est la mise en œuvre du principal du CIO du printemps qui dit "Ne nous appelez pas, nous vous appellerons". L'utilisation du programmeur d'injection de dépendance n'a pas besoin de créer d'objet à l'aide du nouveau mot clé.
Les objets sont une fois chargés dans le conteneur Spring, puis nous les réutilisons chaque fois que nous en avons besoin en récupérant ces objets dans le conteneur Spring à l'aide de la méthode getBean (String beanName).
la source
L'injection de dépendances est au cœur du concept lié à Spring Framework.Tout en créant la structure de n'importe quel projet spring peut jouer un rôle vital, et ici l'injection de dépendances vient en pichet.
En fait, supposons qu'en Java, vous avez créé deux classes différentes en tant que classe A et classe B, et quelles que soient les fonctions disponibles dans la classe B que vous souhaitez utiliser dans la classe A, à ce moment-là, l'injection de dépendance peut être utilisée. où vous pouvez créer un objet d'une classe dans une autre, de la même manière que vous pouvez injecter une classe entière dans une autre classe pour la rendre accessible. de cette façon, la dépendance peut être surmontée.
L'INJECTION PAR DÉPENDANCE, C'EST SIMPLEMENT COLLER DEUX CLASSES ET EN MÊME TEMPS LES GARDER SÉPARÉES.
la source