2008-11-20 6 views
3

J'ai une question sur les références entre projets dans une solution. La plupart de mes applications précédentes ont juste eu un ou deux projets dans la solution, mais cette fois je veux diviser l'application plus loin.Règles empiriques pour l'ajout de références entre projets C#?

Je commence maintenant une nouvelle solution dans Visual Studio 2008, et j'ai créé plusieurs projets sous-jacents pour diviser les parties séparées de mon application. Mais actuellement, je ne fais que créer les différents projets sur un coup de tête, et créer des références entre eux quand j'en ai besoin. Parfois, je me retrouve dans une situation où deux projets doivent se référencer l'un l'autre, mais cela n'est pas autorisé car cela provoquerait une dépendance circulaire.

Y a-t-il des règles/conseils/modèles que je devrais garder à l'esprit lorsque je crée les différents projets et que je les relie ensemble?

Dois-je commencer de l'intérieur et sortir? Les projets «de base» réorientent-ils tous les projets extérieurs, ou peuvent-ils aller de l'extérieur et où les projets indépendants font tous référence au «noyau»? Ou la troisième option où j'ai des affaires dans deux projets, et ils se réfèrent tous les deux à un troisième projet?

Répondre

9

En effet vous ne pouvez pas avoir de références circulaires, mais pour être honnête quel serait l'avantage de scinder la solution en petit projet si vous aviez des interdépendances entre eux?

Habituellement, avant même d'ouvrir Visual Studio, je prends un morceau de papier et divise mon problème en domaines fonctionnels logiques. Vous pouvez dessiner un ensemble Utilitaires en haut et toutes les interfaces graphiques, les services Web et les autres projets finaux en bas. Le projet Utilities ne se référera à aucun autre projet, et ceux du bas ne seront référencés par rien. Ensuite, vous pensez que la fonctionnalité est commune pour ceux-ci, par ex. toutes les interfaces graphiques peuvent partager un projet d'interface utilisateur commun avec des commandes et des dialogues utilisateur communs, et ce projet d'interface utilisateur référencera le projet "modèle objet", etc. Le projet en bas ne peut faire référence qu'à ce qui se trouve au-dessus.

Souvent, lorsque vous avez besoin d'une référence circulaire, vous pouvez facilement la contourner en définissant une interface dans l'assemblage de niveau inférieur et en fournissant une implémentation au niveau supérieur. Sans savoir ce que vous faites exactement, je crains que ce soit le seul conseil que je puisse vous donner.

+0

Merci, cette astuce visuelle était l'indice dont j'avais besoin. Maintenant, je peux aussi dessiner les références sur une feuille de papier, et il est plus facile de déterminer qui devrait faire référence à qui. –

+0

J'ai entendu dire que l'empaquetage par Nuget de composants de projet de base tels que les entités DAL et POCO est une bonne idée, car vous pouvez installer les packages Nuget dans plusieurs solutions. Avez-vous entendu la même chose? Si oui, pourriez-vous m'expliquer comment utiliser l'emballage Nuget dans une telle situation? –

+0

L'avantage de diviser la solution en projets plus petits est pour le code réutilisable. Nous pouvons séparer plus de code réutilisable pour différents projets et faire référence à notre projet LOB. –

4

C'est un peu démodé, mais pour vous aider à décider comment diviser en projets, vous pouvez rechercher "Couplage" et "Cohésion" dans wikipedia. En outre, même si nous considérons parfois ces décisions comme un «style» plutôt que comme une «substance», nous devons nous rappeler que les limites d'assemblage ont un sens, à la fois pour le compilateur et pour l'exécution. Un couple d'exemples de cela ...

  1. Le compilateur C# comprend un mot clé appelé "interne". Pour prendre les meilleures décisions sur l'affacturage dans des projets distincts, vous devriez vraiment comprendre la puissance de cela.

  2. Le compilateur JIT dans l'environnement d'exécution n'injectera jamais un appel de fonction qui traverse une limite d'assemblage, ce qui implique une performance. (La raison est liée à la sécurité d'accès au code).

Il y a beaucoup d'autres exemples, donc la décision fait vraiment une différence.

2

Je vais utiliser une application Winforms à titre d'exemple. Le modèle que j'ai commencé à entrer est ceci. La solution s'appelle Exemple.

Example.Entities - Ce projet contiendra mes objets métier et les heirachy connexes des classes

Example.Dal - Je mets toute logique de logique métier et l'accès aux données dans ce projet (namespace) C'est le code qui charge vos objets métier et les transmet ensuite à un autre calque.

Exemple.Gui - J'ai mis tout mon code utilitaire Winforms et GUI ici et ma méthode d'entrée de démarrage 'principale'. Vous pouvez également choisir d'appeler ce projet Exemple. J'aime toujours utiliser l'espace de noms Example.Gui pour la séparation de code.

Exemple.Test - Vous pouvez mettre tout votre code de test dans ce projet.

J'essaie de générer du code dans les entités s'il appartient à l'un des objets métier ou à une collection d'objets métier. Gui référencera les Entités et Dal (Data Access Layer)

Selon la façon dont vous écrivez votre Dal, il peut référencer vos Entités. Le test doit référencer les entités, Dal et peut-être Gui.

Les entités est sa propre DLL d'assemblage, de sorte que vous pouvez l'utiliser dans d'autres projets. Ou renvoyez-les à partir d'un service .NET SOAP.

La couche GUI doit afficher les composants internes de la couche DAL en tant que boîte noire. Votre application principale ne doit pas se préoccuper de la manière dont les objets métier sont chargés ou conservés. Mais vous devriez utiliser votre projet de test pour tester votre DAL à fond.

+0

Je devrais ajouter ... si vous regardez certains podcasts vidéo .NET Rocks, certains des invités de Carl utilisent aussi de très bonnes mises en page de solutions. – BuddyJoe

Questions connexes