2010-01-12 10 views
7

Je me bats pour éviter les dépendances cycliques. Je sais que je dois masquer l'implémentation avec des interfaces, mais comment gérer une situation avec deux assemblys, où chacun doit soit instancier des classes de l'autre ou appeler une méthode statique à partir de là?Dépendances cycliques - encore une fois

Edit:

Je comprends cela peut être résolu en utilisant un seul assemblage. Nous en avons plus d'un pour la raison suivante:

  • notre "système" se compose de plusieurs composants. Un client peut avoir un seul composant, ou plus. Nous avons donc créé différents assemblages pour différents composants. Cela a du sens - pourquoi déploieriez-vous des choses dont vous n'avez pas besoin - n'est-ce pas un gaspillage de mémoire?
  • choses qui étaient communes à plus de composants, principalement des classes auxiliaires, sont allés à un autre assemblage - encore une fois tous les composants ont besoin de toutes les classes auxiliaires, donc il y a plus d'assemblages
  • Cependant, ces deux applications peuvent parler les uns aux autres - le système Pour les médecins, les demandes sont envoyées au système pour les infirmières, les demandes sont retournées, etc. - et voici où le problème réel est

Avoir les deux composants en conversation est vraiment une des situations que nous avons eues une dépendance cyclique des conflits avant. Cela arrive de temps en temps et quand cela arrive, nous devons trouver une solution - déplacer des classes - et parfois nous devons ajouter un nouvel assemblage. Maintenant, nous avons comme 8-10 assemblages, et il semble que plus vous avez le plus vite ils sont ajoutés :) - Par exemple, nous avons ajouté une fonction générale qui utilise des attributs personnalisés - nous avons donc ajouté un autre assemblage juste pour l'attribut - juste au cas où nous ne serions pas en conflit à l'avenir

Est-ce la voie à suivre? Je sens vraiment que nous faisons quelque chose de fondamentalement faux :)

J'apprécie vraiment votre contribution.

+0

Vous n'êtes pas sûr de l'avoir suffisamment expliqué. Peut-être que vous devriez utiliser une seule assemblée. –

+1

Veuillez modifier la question pour inclure le contexte de domaine et/ou un exemple de code. –

Répondre

10

Je tenterais d'extraire les types fautifs dans un troisième ensemble «commun» que les deux assemblages «parents» référencent.

Je demanderais pourquoi vous avez besoin de plusieurs assemblages en premier lieu, cependant, quand ils dépendent l'un de l'autre. Les assemblées sont des unités de déploiement et peuvent être versionnées séparément les unes des autres. Si vous n'avez pas besoin de cette fonctionnalité, je voudrais tout emballer tout dans un seul assemblage et être fait avec. Cela a les avantages supplémentaires d'accélérer la construction et de simplifier le déploiement.S'il vous plaît essayer d'ajouter plus de contexte à votre question - peut-être il ya quelques détails que nous pouvons vous aider si nous savons exactement ce que vous essayez de faire.

Modifier re vos ajouts: Pour répondre précisément à votre question quant à savoir si ou non de multiples assemblées est la voie à suivre, considérez ceci: J'ai déjà travaillé sur une base de code comme celui-ci avec Visual Studio 2008, où il y avait environ 20 séparé fichiers de projet ouverts dans la solution à la fois. Ces 20 projets prenaient tous en charge les DLL pour un seul EXE principal. Ces projets n'étaient pas partagés avec d'autres produits, ni d'étranges exigences de versionnement.

Travailler avec cette solution était un cauchemar. Il a fallu littéralement 5 minutes à Visual Studio pour compiler la solution. Compiler dans la ligne de commande avec MSBuild a pris 2 minutes. Cela a fait des changements progressifs un exercice de frustration et de douleur. Puisque tous les projets ont été utilisés dans la réalisation de l'exécutable principal, aucun d'entre eux n'a pu être déchargé pour accélérer la compilation, et il y avait un mandat exécutif contre la rupture des projets en solutions séparées. Si vous vous retrouvez avec une seule solution comme celle-ci, croyez-moi quand je dis que vous et vos coéquipiers vous révolterez un jour ... Ma recommandation serait de séparer les assemblées en leurs propres solutions, en regroupant toutes les assemblées qui sont susceptibles d'être changés ensemble; Créez ensuite une tâche de génération personnalisée qui copie l'assemblage final dans un dossier commun à partir duquel tous les autres assemblys peuvent prendre des références.

+0

Erik, merci pour ton commentaire –

+0

Pas de problème - J'espère que ça aide. =) –

3

Pouvez-vous mettre les choses communes dans son propre assemblage? Je suis d'accord avec un intervenant sur le fait que nous avons probablement besoin de plus de renseignements.

Pourquoi avez-vous 2 ensembles?

Y at-il une raison pour laquelle tout n'est pas dans un assemblage?

Comment ces ensembles sont-ils connectés? Juste par référence ou y a-t-il des composants WCF, etc. impliqués?

Nous vous avons donné les réponses les plus simples, mais peut-être y at-il plus que ce que nous pouvons dire grâce à votre brève description.

+0

Souvent, vous avez des cours qui en font trop. Vous devrez peut-être décomposer certaines classes pour trouver des choses communes. –

1

Une façon d'éviter cela serait d'utiliser une structure proxy/métier.

AssemblyA.Proxy - contient deux classes: une interface (appelons-le iServices), et une autre classe responsable d'appeler méthodes AssemblyA.Business.

AssemblyA.Business - contient une classe, qui met en œuvre les méthodes déclarées sur iServices.

AssemblyB.Proxy - analogique AssemblyA.Proxy

AssemblyB.Business - analogique AssemblyA.Business

De cette façon, chaque composant Proxy ne fait référence qu'à la logique métier qu'ils sont censés à. AssemblyA.Proxy aurait une référence à AssemblyA.Business; AssemblyB.Proxy aurait une référence à AssemblyB.Business. AssemblyA.Business référencer AssemblyB.Proxy, et ainsi de suite.

Je ne sais pas si c'est clair mais j'espère que ça aide.

Questions connexes