Injection de dépendances
Au lieu d'instancier les pièces elles-mêmes, une voiture demande pour les pièces dont il a besoin pour fonctionner.
class Car
{
private Engine engine;
private SteeringWheel wheel;
private Tires tires;
public Car(Engine engine, SteeringWheel wheel, Tires tires)
{
this.engine = engine;
this.wheel = wheel;
this.tires = tires;
}
}
Usine
Assemble les pièces pour former un objet complet et cache le type concret à l'appelant.
static class CarFactory
{
public ICar BuildCar()
{
Engine engine = new Engine();
SteeringWheel steeringWheel = new SteeringWheel();
Tires tires = new Tires();
ICar car = new RaceCar(engine, steeringWheel, tires);
return car;
}
}
Résultat
Comme vous pouvez le constater, les usines et l'ID se complètent.
static void Main()
{
ICar car = CarFactory.BuildCar();
// use car
}
Tu te souviens de Boucle d'or et les trois ours ? Eh bien, l'injection de dépendances est un peu comme ça. Voici trois façons de faire la même chose.
void RaceCar() // example #1
{
ICar car = CarFactory.BuildCar();
car.Race();
}
void RaceCar(ICarFactory carFactory) // example #2
{
ICar car = carFactory.BuildCar();
car.Race();
}
void RaceCar(ICar car) // example #3
{
car.Race();
}
Exemple n° 1 - C'est le pire car il masque complètement la dépendance. Si vous regardiez la méthode comme une boîte noire, vous n'auriez aucune idée qu'elle nécessite une voiture.
Exemple n° 2 - C'est un peu mieux car maintenant nous savons que nous avons besoin d'une voiture puisque nous passons dans une usine de voitures. Mais cette fois, nous passons trop de choses puisque la méthode n'a besoin que d'une voiture. Nous passons dans une usine juste pour construire la voiture alors que la voiture pourrait être construite en dehors de la méthode et passée.
Exemple n° 3 - C'est idéal car la méthode demande exactement ce dont il a besoin. Ni trop, ni trop peu. Je n'ai pas besoin d'écrire un MockCarFactory juste pour créer des MockCars, je peux passer le mock directement dedans. C'est direct et l'interface ne ment pas.
Ce Google Tech Talk de Misko Hevery est étonnant et constitue la base de ce dont j'ai tiré mon exemple. http://www.youtube.com/watch?v=XcT4yYu_TTs
23 votes
Ces deux approches ne peuvent-elles pas se compléter l'une l'autre : utiliser l'injection de dépendances pour injecter des classes d'usine ?
21 votes
Ce serait vraiment bien si cette question avait une réponse avec du code ! Je ne vois toujours pas en quoi DI serait bénéfique/différent de l'utilisation d'une factory pour la création ? Il suffit de remplacer cette ligne dans la classe factory pour changer l'objet/implémentation qui est créé ?
2 votes
@gideon cela ne vous obligerait-il pas à compiler votre application, ou au moins le module contenant la classe d'usine ?
1 votes
@liortal yep c'est vrai. J'ai fait une longue étude sur le DI depuis ce commentaire et maintenant je comprends que le DI prend la méthode d'usine un pas en avant.
1 votes
Jetez un coup d'œil à cette excellente réponse : stackoverflow.com/questions/4985455/ - Il l'explique très bien et fournit des exemples de code.
0 votes
Avez-vous déjà vu une utilisation de l'injection de dépendances qui n'utilisait pas de fabriques ? Ce serait bizarre, puisque l'injection de dépendances signifie mettre le code pour créer un objet à un seul endroit, ce qui impose toute la complexité / l'abstraction / la douleur dans le cul d'une usine. Ne serait-il pas stupide d'utiliser l'injection de dépendance mais pas les fabriques ?
0 votes
Pour ajouter mon grain de sel, si quelqu'un est intéressé par la façon dont l'injection de dépendances peut être utile dans un thème de café, j'ai écrit un article à ce sujet ici : digigene.com/design-patterns/dependency-injection-coffeeshop
0 votes
La réponse qui a reçu le plus de votes n'a aucun sens. Le modèle de conception factory utilise le principe d'inversion des dépendances, qui DOIT externaliser l'instanciation du code vers une autre classe. Par conséquent, sa réponse n'a aucun sens.
0 votes
"Un conteneur IOC (comme StructureMap) est juste une usine sur des stéroïdes".
0 votes
Pour réaliser une bonne injection de dépendances, vous devez vous appuyer sur des usines, qui vous permettent de créer une racine de composition, une couche supérieure qui relie tous vos composants découplés en s'adaptant à votre cas d'implémentation. Vous pouvez consulter la bibliothèque Di-Ninja, qui est un bon exemple de code source pour expliquer les objectifs de l'injection de dépendances. github.com/di-ninja/di-ninja