Cio/DI - Pourquoi dois-je avoir pour faire référence à toutes les couches/assemblées en application du point d'entrée?
(Liée à cette question, EF4: Pourquoi la création de proxy être activé lorsque le chargement différé est activé?).
Je suis nouveau sur DI, si patient avec moi. Je comprends que le conteneur est en charge de l'instanciation de l'ensemble de mes types enregistrés, mais pour ce faire, il nécessite une référence à toutes les Dll dans ma solution et de leurs références.
Si je n'étais pas à l'aide d'un conteneur d'injection de dépendances, je n'aurais pas de référence à la EntityFramework bibliothèque dans ma MVC3 app, seulement ma couche de gestion, qui serait la référence de ma DAL/Repo couche.
Je sais qu'à la fin de la journée, toutes les Dll sont inclus dans le dossier bin, mais mon problème c'est d'avoir à faire référence explicitement via "ajouter une référence" dans VS pour être en mesure de publier un WAP avec tous les fichiers nécessaires.
- Ce chapitre dans le livre l'Injection de Dépendance dans la .NET, deuxième édition c'est une version plus élaborée des réponses à la fois de Mark et moi-même. Il décrit en détail le concept de la Composition de la Racine et pourquoi laisser le chemin de démarrage de l'application dépendent de chaque autre module est en fait une bonne chose.
- J'ai lu que l'extrait de lien et le chapitre 1, je vais l'acheter le livre que j'ai vraiment apprécié les analogies et des explications simples, à la question complexe de DI. Je pense que vous devriez proposer une nouvelle réponse, répondre clairement "vous n'avez pas à faire référence à toutes les couches/assemblées dans l'entrée de couche logique, sauf si c'est aussi votre composition de la racine," le lien de l'extrait, et afficher l'image de la Figure 3, à partir de l'extrait.
Vous devez vous connecter pour publier un commentaire.
Oui, c'est exactement la situation DI travaille si dur à éviter 🙂
Étroitement couplé avec code, chaque bibliothèque peut n'avoir que quelques références, mais ces encore avoir d'autres références, la création d'un profond graphe de dépendances, comme ceci:
Parce que le graphe de dépendance est profond, cela signifie que la plupart des bibliothèques glisser le long de beaucoup d'autres dépendances - par exemple, dans le diagramme, Bibliothèque C traîne Bibliothèque H, Bibliothèque Électronique, Bibliothèque J, de la Bibliothèque de M, Bibliothèque K et Bibliothèque N. Cela rend plus difficile la réutilisation chaque bibliothèque indépendamment du reste - par exemple dans les tests unitaires.
Cependant, dans un couplage lâche application, par le transfert de toutes les références à la La Composition De La Racine, le graphe de dépendance est fortement aplatie:
Comme illustré par la couleur verte, il est maintenant possible de réutiliser Bibliothèque C sans le faire glisser le long de tous les indésirables dépendances.
Cependant, tout ce que dit, avec beaucoup de DI Conteneurs, vous n'avez pas ont pour ajouter dur références à toutes les bibliothèques requises. Au lieu de cela, vous pouvez utiliser la liaison tardive soit sous la forme de la convention d'assemblage à base de balayage (de préférence) ou de configuration XML.
Quand vous faites cela, cependant, vous devez ne pas oublier de copier les assemblys dans le dossier bin de l'application, car cela ne se fait plus automatiquement. Personnellement, je trouve rarement il vaut la peine l'effort supplémentaire.
Une version plus élaborée de cette réponse peut être trouvée dans cet extrait de mon livre L'Injection De Dépendance, Des Principes, Des Pratiques, Des Modèles.
IEnumerable<T>
ouIObserver<T>
pour les dépendances. Celles-ci sont définies dans la BCL, donc automatiquement déjà à la disposition de tous les consommateurs et les exécutants.Même lors de l'utilisation d'un conteneur d'injection de dépendances, vous n'avez pas à laisser votre MVC3 projet de référence EF, mais vous (implicitement) choisir de le faire par la mise en œuvre de la La Composition De La Racine (le chemin de démarrage où vous pouvez rédiger votre graphes d'objets) à l'intérieur de votre MVC3 projet. Si vous êtes très stricte sur la protection de vos limites architecturales à l'aide d'assemblages, vous pouvez déplacer votre Composition de la Racine ou de votre (MVC) présentation des choses à une bibliothèque de classe.
Dans la première option, vous laissez votre MVC3 de référence du projet, ce 'programme d'amorçage de l'assemblée, et il fait référence à toutes les autres assemblées dans votre solution de plus la référence de votre conteneur d'injection de dépendances de la bibliothèque. Le problème, c'est que ce programme d'amorçage de projet ne peut pas les types de référence situé dans le MVC3 projet (car cela risque de provoquer une reprise cyclique de l'assemblée de la dépendance). Ces types doivent être déplacés pour le programme d'amorçage de projet (qui peut avoir besoin de Système de référence.Web.Mvc), ou vous avez besoin de garder une petite partie de la configuration du conteneur à l'intérieur de votre MVC3 app. Notez également que votre projet MVC toujours référence à toutes les autres assemblées indirectement par le biais du nouveau programme d'amorçage de l'assemblée, parce que l'assemblée des dépendances transitives.
Bien que de placer la Composition de la Racine dans un ensemble distinct est valide chose à faire, la plupart des DI puriste (moi y compris) ont l'habitude de se déplacer seulement de la composition de la racine à une bibliothèque de classe quand il y a de multiples applications (c'est à dire une application web + web service + service windows) qui utilisent la même couche de gestion. Quand j'ai une seule application que j'ai garder la Composition de la Racine à l'intérieur de mon stage de fin d'application.
La deuxième option est de déplacer toutes les MVC classes associées (vues, contrôleurs, etc) depuis le démarrage du projet pour une bibliothèque de classe. Cela permet à cette nouvelle couche de présentation de l'assemblée pour rester déconnecté du reste de l'application. Votre projet d'application web elle-même deviendra une coquille très mince avec un requis de démarrage de la logique. Le projet d'application web sera la Composition de la Racine qui fait référence à toutes les autres assemblées.
L'extraction de la logique de présentation d'une bibliothèque de classe peut compliquer les choses quand on travaille avec MVC. Il sera plus difficile de fil de tout ce qui, depuis les contrôleurs et les vues, les images, les fichiers css, etc. ne sont pas dans le projet de démarrage. C'est sans doute faisable, mais prendra plus de temps.
Les deux options ont leurs inconvénients et c'est pourquoi j'ai généralement des conseils pour garder juste la Composition de la Racine dans le site web du projet. De nombreux développeurs ne veulent pas que leurs MVC assemblée dépendent de la DAL de l'assemblée, mais ce n'est pas vraiment un problème. N'oubliez pas que les assemblages sont un déploiement artefact; vous code fractionné en plusieurs assemblées pour permettre au code d'être utilisés séparément. Une couche architecturale sur l'autre main est une logique artefact. Il est très bien possible (et fréquent) d'avoir plusieurs couches dans la même assemblée.
Dans ce cas, nous allons finir par avoir la Composition de la Racine (couche) et la Couche de Présentation dans le même projet d'application web (donc dans le même assemblée). Et même si cette assemblée, les références de l'assemblée contenant le DAL, la Présentation Couche encore ne fait pas référence à l'Accès aux Données Couche. C'est une grande distinction.
Bien sûr, quand nous faisons cela, nous perdons la capacité pour le compilateur de vérifier cette architecture règle au moment de la compilation, mais cela ne devrait pas être un problème. La plupart des règles architecturales qui en fait ne peut pas être vérifié par le compilateur et il y a toujours quelque chose comme le sens commun. Et si il n'y a pas de bon sens dans votre équipe, vous pouvez toujours utiliser le code d'examen (chaque équipe doit OMI fais toujours d'ailleurs). Vous pouvez également utiliser un outil tel que NDepend (commerciales), ce qui vous permet de vérifier vos règles architecturales. Lorsque vous intégrez NDepend avec votre processus de création, il peut vous avertir quand quelqu'un a vérifié code qui contrevient à ces architectural de la règle.
Vous pouvez lire une discussion plus détaillée sur la façon dont la Composition de la Racine des œuvres dans le chapitre 4 de mon livre L'Injection De Dépendance, Des Principes, Des Pratiques, Des Modèles.
Vous pouvez créer un autre projet appelé "DependencyResolver".
Dans ce projet, vous avez pour référencer tous vos bibliothèques.
Maintenant la Couche d'INTERFACE utilisateur n'a pas besoin de NHibernate/EF ou tout autre pas de l'INTERFACE utilisateur pertinentes à l'exception de la bibliothèque du Château de Windsor pour être référencé.
Si vous souhaitez masquer le Château de Windsor et DependencyResolver de votre couche d'INTERFACE utilisateur que vous pourriez écrire un HttpModule qui appelle le Cio registre des trucs.
Je n'ai qu'un exemple pour StructureMap:
La DefaultControllerFactory ne pas utiliser le conteneur IoC directement, mais il délègue à conteneur IoC méthodes.
La
GetController
délégué est situé dans un StructureMap de Registre (à Windsor, il devrait être un programme d'installation).