Injection de dépendance vs modèle d’usine

La plupart des exemples cités pour l’utilisation de l’dependency injections peuvent également être résolus en utilisant le modèle d’usine. En ce qui concerne l’utilisation / la conception, la différence entre l’dependency injection et l’usine est floue ou mince.

Une fois que quelqu’un m’a dit que c’est comme ça que vous l’utilisez, ça fait une différence!

Une fois, j’ai utilisé StructureMap un conteneur DI pour résoudre un problème, plus tard, je l’ai repensé pour fonctionner avec une fabrique simple et supprimé les références à StructureMap.

Quelqu’un peut-il me dire quelle est la différence entre eux et où utiliser quoi, quelle est la meilleure pratique ici?

Lorsque vous utilisez une fabrique, votre code est toujours responsable de la création d’objects. Par DI, vous confiez cette responsabilité à une autre classe ou à un cadre distinct de votre code.

Je suggère de garder les concepts simples et simples. La dépendance par injection est plutôt un modèle architectural permettant de coupler librement des composants logiciels. Le motif d’usine n’est qu’un moyen de séparer la responsabilité de créer des objects d’autres classes avec une autre entité. Le motif d’usine peut être appelé comme outil pour implémenter DI. L’dependency injections peut être implémentée de plusieurs manières, comme les DI utilisant des constructeurs, en utilisant le mappage de fichiers XML, etc.

Injection de dépendance

Au lieu d’instancier les pièces elles-mêmes, une voiture demande les pièces dont elle a besoin pour fonctionner.

 class Car { private Engine; private SteeringWheel; private Tires tires; public Car(Engine engine, SteeringWheel wheel, Tires tires) { this.Engine = engine; this.SteeringWheel = wheel; this.Tires = tires; } } 

Usine

Rassemble les pièces pour créer un object complet et masque le type de béton de 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 voir, les usines et les DI se complètent.

 static void Main() { ICar car = CarFactory.BuildCar(); // use car } 

Vous rappelez-vous des boucles d’or et des trois ours? Eh bien, l’dependency injection 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 # 1 – C’est le pire car il cache complètement la dépendance. Si vous regardiez la méthode comme une boîte noire, vous n’auriez aucune idée de la nécessité d’une voiture.

Exemple # 2 – C’est un peu mieux car maintenant nous soaps que nous avons besoin d’une voiture puisque nous passons dans une usine automobile. Mais cette fois, nous passons trop car toute la méthode dont nous avons besoin est une voiture. Nous passons dans une usine juste pour construire la voiture lorsque la voiture pourrait être construite en dehors de la méthode et passée.

Exemple # 3 – Ceci est idéal car la méthode demande exactement ce dont elle a besoin. Pas trop ou trop peu. Je n’ai pas besoin d’écrire un MockCarFactory juste pour créer des MockCars, je peux passer le simulacre directement. C’est direct et l’interface ne ment pas.

Ce Google Tech Talk de Misko Hevery est incroyable et est à la base de mon exemple. http://www.youtube.com/watch?v=XcT4yYu_TTs

Il y a des problèmes faciles à résoudre avec l’dependency injection qui ne sont pas si facilement résolus avec une suite d’usines.

Une partie de la différence entre, d’une part, l’inversion du contrôle et l’dependency injection (IOC / DI) et, d’autre part, un localisateur de services ou une suite d’usines (usine), est:

IOC / DI est un écosystème complet d’objects et de services de domaine en soi. Tout est mis en place selon vos spécifications. Vos objects et services de domaine sont construits par le conteneur et ne se construisent pas eux-mêmes: ils ne sont donc pas dépendants du conteneur ou des usines. IOC / DI permet un niveau de configurabilité extrêmement élevé, avec toute la configuration en un seul endroit (construction du conteneur) dans la couche supérieure de votre application (l’interface graphique, l’interface Web).

Factory élimine une partie de la construction de vos objects et services de domaine. Cependant, les objects et services du domaine sont toujours responsables de la manière de se construire et d’obtenir tout ce dont ils dépendent. Toutes ces dépendances “actives” filtrent complètement toutes les couches de votre application. Il n’y a pas de lieu unique pour tout configurer.

Un inconvénient de DI est qu’il ne peut pas initialiser des objects avec la logique. Par exemple, lorsque je dois créer un personnage qui a un nom et un âge aléatoires, DI n’est pas le choix par rapport au motif d’usine. Avec les usines, nous pouvons facilement encapsuler l’algorithme aléatoire à partir de la création d’object, qui prend en charge l’un des modèles de conception appelés “Encapsuler ce qui varie”.

La gestion du cycle de vie est l’une des responsabilités assumées par les conteneurs de dépendance en plus de l’instanciation et de l’injection. Le fait que le conteneur garde parfois une référence aux composants après l’instanciation est la raison pour laquelle il est appelé “conteneur”, et non une fabrique. Les conteneurs d’dependency injection ne conservent généralement qu’une référence aux objects dont ils ont besoin pour gérer les cycles de vie ou qui sont réutilisés pour de futures injections, comme les singletons ou les poids volants. Lorsqu’il est configuré pour créer de nouvelles instances de certains composants pour chaque appel au conteneur, le conteneur oublie généralement l’object créé.

De: http://tutorials.jenkov.com/dependency-injection/dependency-injection-containers.html

La raison pour laquelle l’dependency injections (DI) et les motifs d’usine sont similaires est due au fait qu’il s’agit de deux implémentations d’Inversion of Control (IoC), une architecture logicielle. Dit simplement, ce sont deux solutions au même problème.

Donc, pour répondre à la question, la principale différence entre le motif Factory et DI est la façon dont la référence d’object est obtenue. Avec l’dependency injection comme son nom l’indique, la référence est injectée ou donnée à votre code. Avec le motif d’usine, votre code doit demander la référence afin que votre code récupère l’object. Les deux implémentations suppriment ou découplent la liaison entre le code et la classe ou le type sous-jacent de la référence d’object utilisée par le code.

Il est intéressant de noter que les patterns Factory (ou les Factory Abstract qui sont des fabriques qui renvoient de nouvelles usines renvoyant des références d’objects) peuvent être écrits pour choisir ou lier dynamicment le type ou la classe d’object demandé lors de l’exécution. Cela les rend très similaires (encore plus que DI) au modèle de localisateur de services, qui est une autre implémentation de l’IoC.

Le modèle de conception Factory est assez ancien (en termes de logiciel) et existe depuis un certain temps. Depuis la récente popularité du modèle architectural, IoC connaît un regain.

En ce qui concerne les modèles de conception de l’IoC, je suppose: les injecteurs sont injectés, les localisateurs sont localisés et les usines ont été remises à neuf.

Je crois que le DI est un type de couche d’abstraction sur les usines, mais elles offrent également des avantages au-delà de l’abstraction. Une véritable usine sait instancier un seul type et le configurer. Une bonne couche DI permet, grâce à la configuration, d’instancier et de configurer de nombreux types.

Evidemment, pour un projet avec quelques types simples nécessitant une logique métier relativement stable dans leur construction, le modèle d’usine est simple à comprendre, à mettre en œuvre et fonctionne bien.

OTOH, si vous avez un projet contenant de nombreux types dont vous vous attendez à changer souvent les implémentations, la configuration de DI vous permet de le faire lors de l’exécution sans avoir à recomstackr vos usines.

Je sais que cette question est ancienne mais je voudrais append mes cinq cents,

Je pense que l’dependency injection (DI) est à bien des égards comme un modèle d’usine configurable (FP) et, en ce sens, tout ce que vous pourriez faire avec DI vous permettra de le faire avec une telle usine.

En fait, si vous utilisez Spring, par exemple, vous avez la possibilité d’auto-activer des ressources (DI) ou de faire quelque chose comme ceci:

 MyBean mb = ctx.getBean("myBean"); 

Et puis utilisez cette instance ‘mb’ pour faire n’importe quoi. N’est-ce pas un appel à une usine qui vous renverra une instance?

La seule vraie différence que je remarque entre la plupart des exemples de FP est que vous pouvez configurer ce que “myBean” contient dans un xml ou dans une autre classe, et un framework fonctionnera comme une fabrique, mais à part ça, c’est la même chose et vous peut avoir certainement une Factory qui lit un fichier de configuration ou obtient l’implémentation en fonction de ses besoins.

Et si vous me demandez mon avis (Et je sais que vous ne l’avez pas fait), je pense que DI fait la même chose mais ajoute simplement plus de complexité au développement, pourquoi?

Eh bien, pour une chose, pour que vous sachiez quelle est la mise en œuvre utilisée pour tout bean que vous utilisez avec DI, vous devez aller à la configuration elle-même.

mais… que diriez-vous que vous n’aurez pas à connaître la mise en œuvre de l’object que vous utilisez? pfft! sérieusement? Lorsque vous utilisez une approche comme celle-ci, n’êtes-vous pas le même qui écrit l’implémentation? Et même si vous ne le faites pas, ne vous attendez-vous pas presque tout le temps à voir comment la mise en œuvre fait ce qu’elle est censée faire?

Et pour une dernière chose, peu importe à quel point un framework DI vous promet de construire des choses découplées , sans aucune dépendance à leurs classes, si vous utilisez un framework que vous construisez tout, si vous devez changer l’approche ou le cadre ce ne sera pas une tâche facile … JAMAIS! … mais comme vous construisez tout autour de ce cadre particulier au lieu de vous inquiéter de la meilleure solution pour votre entreprise, vous devrez alors faire face à un problème de taille.

En fait, la seule véritable application métier pour une approche FP ou DI que je peux voir est que si vous devez modifier les implémentations utilisées à l’ exécution , mais au moins les frameworks que je connais ne vous permettent pas de le faire, vous devez quitter tout est parfait dans la configuration au moment du développement et si vous avez besoin d’une autre approche.

Donc, si j’ai une classe qui fonctionne différemment dans deux étendues dans la même application (disons deux sociétés d’un holding), je dois configurer le framework pour créer deux beans différents et adapter mon code pour les utiliser chacun. N’est-ce pas la même chose que si je voulais juste écrire quelque chose comme ceci:

 MyBean mb = MyBeanForEntreprise1(); //In the classes of the first enterprise MyBean mb = MyBeanForEntreprise2(); //In the classes of the second enterprise 

la même chose que ceci:

 @Autowired MyBean mbForEnterprise1; //In the classes of the first enterprise @Autowired MyBean mbForEnterprise2; //In the classes of the second enterprise 

Et ça:

 MyBean mb = (MyBean)MyFactory.get("myBeanForEntreprise1"); //In the classes of the first enterprise MyBean mb = (MyBean)MyFactory.get("myBeanForEntreprise2"); //In the classes of the second enterprise 

Dans tous les cas, vous devrez changer quelque chose dans votre application, qu’il s’agisse de classes ou de fichiers de configuration, mais vous devrez le redéployer.

Ne serait-il pas agréable de faire quelque chose comme ça:

 MyBean mb = (MyBean)MyFactory.get("mb"); 

Et de cette façon, vous définissez le code de la fabrique pour obtenir la bonne implémentation à l’exécution en fonction de l’entreprise de l’utilisateur connecté. Maintenant, ce serait utile. Vous pouvez simplement append un nouveau fichier jar avec les nouvelles classes et définir les règles peut-être même à l’exécution (ou append un nouveau fichier de configuration si vous laissez cette option ouverte), aucune modification aux classes existantes. Ce serait une usine dynamic!

Ne serait-ce pas plus utile que d’écrire deux configurations pour chaque entreprise et peut-être même d’avoir deux applications différentes pour chaque entreprise?

Vous pouvez me dire, je n’ai pas besoin de faire le changement à l’exécution, donc je configure l’application, et si j’hérite de la classe ou utilise une autre implémentation, je change juste la configuration et redéploie. Ok, ça peut aussi être fait avec une usine. Et soyez honnête, combien de fois faites-vous cela? peut-être seulement lorsque vous avez une application qui sera utilisée ailleurs dans votre entreprise, et que vous allez transmettre le code à une autre équipe, et ils vont faire des choses comme ça. Mais bon, cela peut aussi se faire avec l’usine, et ce serait encore mieux avec une usine dynamic !!

En tout cas, la section des commentaires est ouverte pour que tu me tues.

Théorie

Il y a deux points importants à considérer:

  1. Qui crée des objects

    • [Factory]: Vous devez écrire COMMENT object doit être créé. Vous avez une classe Factory séparée qui contient la logique de création.
    • [Injection de dépendances]: Dans la pratique, les cas sont réalisés par des frameworks externes (par exemple, en Java, ce serait Spring / ejb / Guice). L’injection se passe “par magie” sans explicite création de nouveaux objects
  2. Quel genre d’objects il gère:

    • [Factory]: Généralement responsable de la création d’objects avec état
    • [Injections de dépendances] Plus susceptibles de créer des objects sans état

Exemple pratique d’utilisation de l’injection d’usine et de dépendance dans un projet unique

  1. Ce que nous voulons construire

Module d’application pour créer une commande contenant plusieurs entrées appelées ligne de commande.

  1. Architecture

Supposons que nous voulons créer une architecture de couche suivante:

entrer la description de l'image ici

Les objects de domaine peuvent être des objects stockés dans la firebase database. Repository (DAO) aide à récupérer des objects de la firebase database. Le service fournit une API à d’autres modules. Permet des opérations sur le module de order

  1. Domaine Couche et utilisation des usines

Les entités qui figureront dans la firebase database sont Order et OrderLine. L’ordre peut avoir plusieurs lignes de commande. Relation entre la commande et la ligne de commande

Maintenant vient la partie importante du design. Les modules en dehors de celui-ci doivent-ils créer et gérer les lignes de commande elles-mêmes? Non. La ligne de commande ne doit exister que lorsque vous y êtes associé. Il serait préférable de cacher l’implémentation interne aux classes externes.

Mais comment créer une commande sans connaissance de OrderLines?

Usine

Quelqu’un qui veut créer une nouvelle commande a utilisé OrderFactory (qui masquera les détails sur le fait de créer la commande).

entrer la description de l'image ici

C’est comme ça que ça va regarder à l’intérieur de l’IDE. Les classes hors package de domain utiliseront OrderFactory au lieu du constructeur dans Order

  1. Injection de dépendance L’dependency injection est plus couramment utilisée avec les couches sans état telles que le référentiel et le service.

OrderRepository et OrderService sont gérés par un cadre d’dependency injection. Le référentiel est chargé de gérer les opérations CRUD sur la firebase database. Service injecte Repository et l’utilise pour enregistrer / trouver les classes de domaine correctes.

entrer la description de l'image ici

Avec l’dependency injection, le client n’a pas besoin d’avoir ses propres dépendances, tout est préparé à l’avance.

Avec les usines, quelqu’un doit les appeler pour amener les objects générés à l’endroit où ils sont nécessaires.

La différence réside principalement dans cette ligne où l’appel de la fabrique et la récupération de l’object construit sont effectués.

Mais avec les usines, vous devez écrire cette ligne partout où vous avez besoin d’un tel object. Avec DI, il suffit de créer le câblage (relation entre usage et object créé) une seule fois et de ne compter que sur la présence de l’object partout par la suite. D’un autre côté, le DI nécessite souvent un peu plus de travail (combien dépend du cadre) du côté de la préparation.

IOC est un concept qui est mis en œuvre de deux manières. La création de dépendances et l’dependency injections, Factory / Abstract factory sont l’exemple de la création de dépendances. L’dependency injection est constructeur, setter et interface. Le cœur d’IOC est de ne pas dépendre des classes concrètes, mais de définir l’abrégé des méthodes (par exemple, une classe d’interface / abstraite) et d’utiliser ce résumé pour appeler la méthode de la classe concrète. Like Factory retourne la classe ou l’interface de base. Injection de dépendances similaire utilise la classe de base / interface pour définir la valeur des objects.

J’ai eu la même question dès que j’ai lu à propos de DI et s’est retrouvé à ce poste. Donc finalement c’est ce que j’ai compris mais s’il vous plaît corrigez-moi si je me trompe.

“Il y a longtemps, il y avait de petits royaumes dotés de leurs propres organes de direction qui contrôlaient et prenaient leurs propres décisions écrites. Plus tard, ils formèrent un grand gouvernement éliminant tous ces petits organes de gouvernance (constitution) et appliqués par les sortingbunaux”

Les instances dirigeantes des petits royaumes sont des “usines”

Le grand gouvernement est l’injecteur de dépendance.

Vous pouvez consulter ce lien pour une comparaison des deux approches (et d’autres) dans un exemple réel.

Fondamentalement, lorsque les exigences changent, vous finissez par modifier plus de code si vous utilisez des usines au lieu de DI.

Ceci est également valable avec la DI manuelle (c’est-à-dire quand il n’y a pas de structure externe fournissant les dépendances à vos objects, mais que vous les transmettez dans chaque constructeur).

Je pense que le DI est un moyen de configurer ou d’instancier un bean. Le DI peut être fait de plusieurs manières, comme constructeur, getter-getter, etc.

Le motif d’usine est juste une autre manière d’instancier les grains. Ce modèle sera utilisé principalement lorsque vous devez créer des objects en utilisant le modèle de conception d’usine, car en utilisant ce modèle, vous ne configurez pas les propriétés d’un bean, seulement instanciez l’object.

Vérifiez ce lien: Injection de dépendance

Binoj,

Je ne pense pas que vous devez choisir l’un sur l’autre.

Le fait de déplacer une classe ou une interface dépendante vers un constructeur ou un configurateur de classe suit le modèle DI. L’object que vous transmettez au constructeur ou à l’ensemble peut être implémenté avec Factory.

Quand utiliser? Utilisez le ou les motifs de la timonerie de votre développeur. Qu’est-ce qu’ils se sentent le plus à l’aise et trouve plus facile à comprendre.

Mes pensées:

Dependecy Injection: transmet les collaborateurs en tant que parameters aux constructeurs. Dependency Injection Framework: une fabrique générique et configurable pour créer les objects à transmettre en tant que parameters aux constructeurs.

Un cadre d’injection est une implémentation du modèle d’usine.

Tout dépend de vos besoins. Si vous avez besoin d’implémenter le modèle d’usine dans une application, il est fort probable que vos exigences seront satisfaites par l’une des nombreuses implémentations de la structure d’injection.

Vous ne devez déployer votre propre solution que si vos besoins ne peuvent être satisfaits par aucun des frameworks tiers. Plus vous écrivez de code, plus vous devez gérer de code. Le code est un passif et non un atout.

Les arguments sur l’implémentation à utiliser ne sont pas aussi fondamentaux que la compréhension des besoins architecturaux de votre application.

Motif de conception d’usine

Le modèle de conception d’usine est caractérisé par

  • Une interface
  • Classes d’implémentation
  • Une usine

Vous pouvez observer peu de choses lorsque vous vous interrogez comme ci-dessous

  • Quand la fabrique créera-t-elle un object pour les classes d’implémentation – exécution ou compilation?
  • Que faire si vous souhaitez modifier l’implémentation au moment de l’exécution? – pas possible

Celles-ci sont traitées par dependency injection.

Injection de dépendance

Vous pouvez avoir différentes façons d’injecter une dépendance. Pour plus de simplicité, passons avec l’Injection d’Interface

Dans DI, le conteneur crée les instances nécessaires et les “injecte” dans l’object.

Élimine ainsi l’instanciation statique.

Exemple:

 public class MyClass{ MyInterface find= null; //Constructor- During the object instantiation public MyClass(MyInterface myInterface ) { find = myInterface ; } public void myMethod(){ find.doSomething(); } } 

À partir d’une valeur nominale, ils ont la même apparence

En termes très simples, un motif de création, un motif de création, nous aide à créer un object – “Définir une interface pour créer un object”. Si nous avons un type de pool d’objects (par exemple Dictionary), en transmettant la clé à Factory (je me réfère au Pattern Simple Factory), vous pouvez résoudre le Type. Travail terminé! Le cadre d’dependency injections (comme la structure, Ninject, l’unité, etc.) semble faire la même chose.

Mais … “Ne réinvente pas la roue”

D’un sharepoint vue architectural, c’est une couche de liaison et “Ne réinventez pas la roue”.

Pour une application d’entreprise, le concept de DI est davantage une couche architecturale qui définit des dépendances. Pour simplifier cela, vous pouvez considérer cela comme un projet de bibliothèque séparé, qui résout les dépendances. L’application principale dépend de ce projet où le résolveur de dépendance fait référence à d’autres implémentations concrètes et à la résolution des dépendances.

En plus de “GetType / Create” depuis une Factory, nous avons le plus souvent besoin de plus de fonctionnalités (possibilité d’utiliser XML pour définir des dépendances, des simulations et des tests unitaires, etc.). Comme vous avez fait référence à la structure, consultez la liste des fonctionnalités de la structure . C’est clairement plus que simplement résoudre un simple mapping d’object. Ne réinventez pas la roue!

Si tout ce que vous avez est un marteau, tout ressemble à un clou

Selon vos besoins et le type d’application que vous créez, vous devez faire un choix. Si elle ne comporte que peu de projets (peut-être un ou deux ..) et implique peu de dépendances, vous pouvez choisir une approche plus simple. C’est comme utiliser un access aux données ADO .Net via Entity Framework pour un simple appel à 1 ou 2 bases de données, où l’introduction de EF est une surcharge dans ce scénario.

Mais pour un projet plus important ou si votre projet s’agrandit, je vous recommande fortement d’avoir une couche DI avec un framework et de faire de la place pour changer le framework DI que vous utilisez (utilisez une façade dans l’application principale (Web App, Web Api, Desktop). ..etc.).

Je crois que 3 aspects importants régissent les objects et leur utilisation:
1. Instanciation (d’une classe avec initialisation s’il y en a).
2. Injection (de l’instance ainsi créée) où elle est requirejse.
3. Gestion du cycle de vie (de l’instance ainsi créée).

En utilisant le motif d’usine, le premier aspect (instanciation) est atteint mais les deux autres sont discutables. La classe qui utilise d’autres instances doit coder en dur les fabriques (au lieu de créer des instances), ce qui gêne les capacités de couplage. De plus, la gestion du cycle de vie des instances devient un défi dans une grande application où une usine est utilisée à plusieurs endroits (en particulier, si l’usine ne gère pas le cycle de vie de l’instance renvoyée, elle devient moche).

En utilisant un DI (de modèle IoC) par contre, tous les 3 sont abstraits en dehors du code (vers le conteneur DI) et le bean géré n’a besoin de rien de cette complexité. Le couplage lâche , un objective architectural très important peut être atteint tranquillement confortablement. Un autre objective architectural important, la séparation des préoccupations peut être atteint beaucoup mieux que les usines.

Alors que les usines pourraient convenir à de petites applications, les grandes seraient mieux de choisir DI par rapport aux usines.

La plupart des réponses ici expliquent la différence conceptuelle et les détails de mise en œuvre des deux. Cependant, je n’ai pas pu trouver d’explication sur la différence d’application que l’OMI est la plus importante et à laquelle le PO a fait référence. Alors laissez-moi rouvrir ce sujet …

Une fois que quelqu’un m’a dit que c’est comme ça que vous l’utilisez, ça fait une différence!

Exactement. Dans 90% des cas, vous pouvez obtenir une référence à un object en utilisant soit Factory, soit DI, et vous vous retrouvez généralement avec ces derniers. Dans 10% des cas, l’utilisation de Factory n’est que correcte . Ces cas incluent l’obtention d’objects par variable aux parameters d’exécution. Comme ça:

 IWebClient client = factoryWithCache.GetWebClient(url: "stackoverflow.com", useCookies: false, connectionTimeout: 120); 

Dans ce cas, il n’est pas possible d’obtenir un client partir de DI (ou du moins, il nécessite une solution de contournement). Donc, en règle générale, pour prendre une décision: si une dépendance peut être obtenue sans aucun paramètre calculé à l’exécution, alors DI est préférable, sinon utilisez Factory.

Avec une usine, vous pouvez grouper les interfaces associées, donc si les parameters passés peuvent être regroupés dans une fabrique, alors c’est aussi une bonne solution pour regarder l’ constructor overinjection dans ce code *):

 public AddressModelFactory(IAddressAtsortingbuteService addressAtsortingbuteService, IAddressAtsortingbuteParser addressAtsortingbuteParser, ILocalizationService localizationService, IStateProvinceService stateProvinceService, IAddressAtsortingbuteFormatter addressAtsortingbuteFormatter) { this._addressAtsortingbuteService = addressAtsortingbuteService; this._addressAtsortingbuteParser = addressAtsortingbuteParser; this._localizationService = localizationService; this._stateProvinceService = stateProvinceService; this._addressAtsortingbuteFormatter = addressAtsortingbuteFormatter; } 

Regardez le constructeur, il vous suffit de passer le IAddressModelFactory , donc moins de parameters *):

  public CustomerController(IAddressModelFactory addressModelFactory, ICustomerModelFactory customerModelFactory, IAuthenticationService authenticationService, DateTimeSettings dateTimeSettings, TaxSettings taxSettings, ILocalizationService localizationService, IWorkContext workContext, IStoreContext storeContext, ICustomerService customerService, ICustomerAtsortingbuteParser customerAtsortingbuteParser, ICustomerAtsortingbuteService customerAtsortingbuteService, IGenericAtsortingbuteService genericAtsortingbuteService, ICustomerRegistrationService customerRegistrationService, ITaxService taxService, CustomerSettings customerSettings, AddressSettings addressSettings,... 

Vous voyez dans CustomerController beaucoup de parameters passés, Oui, vous pouvez voir cela comme une constructor overinjection mais c’est comme ça que DI fonctionne. Et rien ne va pas avec le CustomerController .

*) Le code provient de nopCommerce.

En termes simples, la méthode d’dependency injection par rapport à la méthode d’usine implique respectivement un mécanisme de poussée et de traction.

With pull mechanism : class indirectly have dependency on Factory Method which in turn have dependency on concrete classes.

With Push mechanism : Root component can be configured with all dependent components in a single location and thus promoting high maintenance and loose coupling.

With Factory method responsibility still lies with class (though indirectly) to create new object where as with dependency injection that responsibility is outsourced (at the cost of leaking abstraction though)

I think these are orthogonal and can be used together. Let me show you an example I recently came across at work:

We were using the Spring framework in Java for DI. A singleton class ( Parent ) had to instantiate new objects of another class ( Child ), and those had complex collaborators:

 @Component class Parent { // ... @Autowired Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) { this.dep1 = dep1; this.dep2 = dep2; } void method(int p) { Child c = new Child(dep1, dep2, ..., depN, p); // ... } } 

In this example, Parent has to receive DepX instances only to pass them to the Child constructor. Problems with this:

  1. Parent has more knowledge of Child than it should
  2. Parent has more collaborators than it should
  3. Adding dependencies to Child involves changing Parent

This is when I realized a Factory would fit here perfectly:

  1. It hides all but the true parameters of the Child class, as seen by Parent
  2. It encapsulates the knowledge of creating a Child , which can be centralized in the DI configuration.

This is the simplified Parent class and the ChildFactory class:

 @Component class Parent { // ... @Autowired Parent(ChildFactory childFactory) { this.childFactory = childFactory; } void method(int p) { Child c = childFactory.newChild(p); // ... } } @Component class ChildFactory { // ... @Autowired Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) { this.dep1 = dep1; this.dep2 = dep2; // ... this.depN = depN; } Child newChild(int p) { return new Child(dep1, dep2, ..., depN, p); } } 

I use both to create an Inversion Of Control strategy with more readability for developers who need to maintain it after me.

I use a Factory to create my different Layer objects (Business, Data Access).

 ICarBusiness carBusiness = BusinessFactory.CreateCarBusiness(); 

Another developer will see this and when creating an Business Layer object he looks in BusinessFactory and Intellisense gives the developer all the possible Business Layers to create. Doesn’t have to play the game, find the Interface I want to create.

This structure is already Inversion Of Control. I am no longer responsible for creating the specific object. But you still need to ensure Dependency Injection to be able to change things easily. Creating your own custom Dependency Injection is ridiculous, so I use Unity. Within the CreateCarBusiness() I ask Unity to Resolve which class belongs to this and it’s lifetime.

So my code Factory Dependency Injection structure is:

 public static class BusinessFactory { public static ICarBusiness CreateCarBusiness() { return Container.Resolve(); } } 

Now I have the benefit of both. My code is also more readable for other developers as towards scopes of my objects I use, instead of Constructor Dependency Injection which just says every object is available when the class is created.

I use this to change my Database Data Access to a custom coded Data Access layer when I create Unit Tests. I don’t want my Unit Tests to communicate with databases, webservers, e-mail servers etc. They need to test my Business Layer because that’s where the intelligence is.

Using dependency injection is much better in my opinion if you are: 1. deploying your code in small partition, because it handles well in decoupling of one big code. 2. testability is one of the case DI is ok to use because you can mock easily the non decoupled objects. with the use of interfaces you can easily mock and test each objects. 3. you can simultaneously revised each part of the program without needing to code the other part of it since its loosely decoupled.