Bonne pratique sur les solutions Visual Studio [fermé]

10

Si tout va bien une question de relativité simple. Je commence à travailler sur un nouveau projet interne pour créer la tractabilité des appareils réparés dans les bâtiments.

La base de données est stockée à distance sur un serveur Web et sera accessible via l'API Web (sortie JSON) et protégée avec OAuth. L'interface graphique frontale est en cours dans WPF, et le code d'entreprise en C #.

De là, je vois les différentes couches Présentation / Application / Datastore. Il y aura du code pour gérer tous les appels authentifiés à l'API, une classe pour représenter les entités (objets métier), des classes pour construire les entités (objets métier), des parties pour l'interface graphique WPF, des parties des modèles de vue WPF, etc.

Est-il préférable de créer cela dans un seul projet ou de les diviser en projets individuels?

Dans mon cœur, je dis que ce devrait être de multiples projets. Je l'ai fait dans les deux sens auparavant et j'ai trouvé que les tests étaient plus faciles avec une seule solution de projet, mais avec plusieurs projets, des dépendances récursives peuvent apparaître. Surtout quand les classes ont des interfaces pour le rendre plus facile à tester, j'ai trouvé que les choses pouvaient devenir gênantes.

JonWillis
la source
1
Je les séparerais dans ce qui a du sens pour le projet.
Ramhound
Quelqu'un d'autre a-t-il des idées, une sur le projet de tenir les interfaces comme l'a suggéré MattDavey. J'ai utilisé cette approche avant afin d'éviter les dépendances mentionnées. Ou les interfaces de la classe x doivent-elles être placées dans le même projet que la classe x.
JonWillis
De plus, quels calques utilisez-vous tous? J'ai vu quelques variantes différentes bien que les principales soient Présentation / Application / Infrastructure. Certains divisent également l'application en 2 parties, application + service. Certains modèles mentionnent également une couche spécifique pour la logique métier, qui pour moi pourrait être incluse dans les objets métier eux-mêmes.
JonWillis

Réponses:

8

Cela dépend de la taille du projet

Voici les directives que j'ai tendance à utiliser

  • Un petit projet, avec une poignée de pages ou moins, je m'en tiens presque toujours à un seul projet.

  • Si la couche d'accès aux données du petit projet est grande ou complexe, je pourrais la séparer en sa propre couche, mais sinon elle se trouve simplement dans son propre dossier.

  • Si le projet est plus grand, j'aurai presque toujours un projet distinct pour le DAL, et tout fractionnement supplémentaire dépend de l'emplacement des limites entre les fonctionnalités de l'application.

  • Si l'application a plusieurs objectifs, chacun avec ses propres vues, modèles de vue, etc., je séparerai généralement chaque pièce dans sa propre zone. Si chaque section est petite, je les sépare par un dossier. Si chaque section est grande, je les séparerai par un projet.

  • Si j'ai plusieurs projets qui ont besoin de faire référence à la même série d'objets ( ViewModelBase, RelayCommand, etc.), je vais créer un projet juste pour les objets d'infrastructure partagée.

  • Si j'ai une grande quantité de styles / modèles / ressources personnalisés partagés, je vais créer un projet juste pour ceux-ci.

En remarque, j'ai fait une erreur avec mon premier grand projet WPF et je les ai séparés en mettant des modèles dans un projet, des vues dans un autre et des ViewModels dans un troisième. Je peux vous dire maintenant que ce n'est pas la voie à suivre, car l'entretien devient un cauchemar :)

Rachel
la source
Curieux, quels problèmes de maintenance avez-vous rencontrés en séparant les couches?
Ian
@Rachel, j'utiliserai WPF. Je serais donc intéressé de savoir comment vous avez organisé le projet à la fin. Je pense que je me souviens qu'un petit projet MVC a été une douleur lors de la séparation de 3 parties en 3 DLL. Pour WPF, Ma vue sera l'interface graphique, l'entité / l'objet métier à modifier et le ViewModel l'interaction entre eux. Le ViewModel traiterait de la logique d'appeler un référentiel pour charger / enregistrer les réparations (qui à leur tour ont des usines / des API Web, etc.).
JonWillis
1
@Ian Le plus gros problème était que la plupart des changements mineurs, tels que l'ajout d'un seul champ, m'obligeaient à rechercher le modèle, la vue, le modèle de vue et le DAL dans 4 bibliothèques distinctes. Le projet sur lequel je travaillais à l'époque était assez important et j'ai perdu plus de temps que je ne le souhaitais à rechercher des fichiers spécifiques. Depuis, je l' ai changé pour garder des objets liés ensemble, donc par exemple tout ce qui concerne la recherche, tels que SearchView, SearchViewModelet SearchResultModelseraient tous regroupés dans un dossier et je l' ai trouvé rend l'application plus facile à entretenir.
Rachel
@Ian Je me souviens également d'avoir eu des problèmes de dépendance et d'avoir rencontré des références circulaires, car malgré mes efforts, certaines couches devaient en référencer d'autres, mais cette couche les référençait, j'ai donc eu des solutions de contournement moches jusqu'à ce que je les refactorise
Rachel
1
@JonWillis La plupart de mes projets WPF sont répartis en fonction des points spécifiés dans ma réponse. Habituellement, le DAL est sa propre couche, et chaque module ou section du projet est regroupé (dans son propre dossier, espace de noms ou projet selon la taille du projet). Ainsi, par exemple, tous les objets de recherche seraient ensemble, y compris Interfacepour la couche de données, mais la couche d'accès aux données réelle pour la recherche serait dans la bibliothèque DAL. Très souvent, j'ai une bibliothèque Infrastructureou Commonqui contient des classes de base, des interfaces et des classes d'assistance communes.
Rachel
14

J'ai vu les meilleurs résultats avec un projet par couche, plus un projet de test par couche. J'ai vu peu d'applications qui ne peuvent pas être réalisées dans 10 projets ou moins dans la solution, où la solution englobe tout .

Ne tombez pas dans le piège d'utiliser des projets où vous voulez vraiment un espace de noms. Des tonnes de projets n'ajoutent que des frais généraux sans aucun gain.

Bryan Boettcher
la source
9

IMHO séparé est presque toujours mieux. Je sépare presque toujours ma couche de données, sauf si le projet est 100% trivial. La raison en est que la couche de données a tendance à être transmise le plus souvent. Il est rare que vous connectiez une interface graphique à plusieurs couches de données et que vous vous attendiez à ce qu'elle fonctionne bien. Le scénario le plus courant est que vous avez une seule couche de données et que vous souhaitez qu'elle soit distribuée sur plusieurs interfaces graphiques (ASP.Net, WPF et une application Silverlight par exemple). C'est génial quand vous pouvez simplement construire le projet de couche de données et mettre cette DLL comme référence dans la prochaine interface graphique que vous créez.

Morgan Herlocker
la source
+1 Lorsque je démarre de nouveaux projets, je crée assez souvent une couche de données simulées qui contient les données en mémoire. Me permet de commencer à créer le reste de l'application en premier. Ensuite, je pourrai l'échanger contre une "vraie" couche d'accès aux données plus tard ..
MattDavey
Considérez-vous que les entités (DTO), les usines et les classes utilisées pour communiquer avec le serveur Web font toutes partie de la couche de données?
JonWillis
@JonWillis - Non, probablement pas tous. Je mettrais les usines et les classes pour le serveur Web dans un espace de noms d'un projet de bibliothèque de classes. Ma couche de données typique ne contient que les fichiers dbml et / ou les fichiers edmx nécessaires. En règle générale, cependant, je donne aux trucs "bibliothèque / framework" leur propre projet. Ils n'ont certainement pas besoin d'être impliqués dans le projet GUI, bien que je vois des gens le faire tout le temps.
Morgan Herlocker
En réalité, combien de temps cela vous prendrait-il pour prendre quelques espaces de noms et les ramifier dans un nouveau projet. Je pense que c'est un travail de refactorisation assez facile.
Didier A.
4

Pour moi, 4 * est le nombre magique. Un projet pour chaque couche et un projet qui définit toutes les interfaces / DTO nécessaires pour communiquer entre elles.

* 7 si vous comptez les tests unitaires

MattDavey
la source
2

J'ai toujours utilisé une seule solution si je travaille sur ces différentes couches, ou s'il y a un couplage étroit avec elles. Je veux toucher F5 et faire reconstruire tous les projets si nécessaire. Je ne pense pas qu'il existe une "bonne" façon de procéder.

Jeremy
la source
2

Son goût personnel, le plus important est d'être cohérent . J'ai personnellement un projet séparé pour chaque couche de l'application, la séparation est donc évidente.

Tom Squires
la source
À quelles couches vous séparez-vous? Avez-vous des couches Application / Services distinctes, et si oui, comment diffèrent-elles réellement? Votre logique métier est-elle contenue dans l'application / le service, ou s'agit-il de méthodes sur les objets métier réels?
JonWillis
1

L'augmentation du nombre de projets est liée à l'activation des tests unitaires et à la simplification du graphique de dépendance au point où les choses ne sont pas si complexes que les changements dans une partie de l'application cassent les choses dans des parties apparemment sans rapport avec l'application.

Cela fonctionne quand je fais une sorte d'inversion de dépendance, pour mettre tous les «contrats», interfaces, classes abstraites, objets de transfert de données dans un seul assemblage. Dans une autre assemblée, j'ai mis tout ce qui parle à la base de données. Les tests unitaires obtiennent leur propre assemblage. Si l'interface utilisateur est fondamentalement non testable (par exemple, les winforms ASP.NET), alors il y a un avantage significatif à diviser l'interface utilisateur en code testable et code non testable - un assemblage chacun. Parfois, du code commence à apparaître qui n'a rien à voir avec la base de données, l'interface utilisateur ou tout ce que j'ai mentionné jusqu'à présent - c'est un code que je souhaitais en quelque sorte être dans le cadre .NET. Ce code que je mettrai dans un assemblage d'utilitaires, ou du moins le mettrai dans quel que soit l'assemblage racine (probablement celui avec les interfaces.

Si tous les assemblys font référence à tous les assemblages, ou presque, ils doivent être fusionnés en un seul assemblage. Si vous ou les membres de votre équipe n'avez pas la discipline nécessaire pour ne pas mettre de code de niveau de données dans l'interface utilisateur et l'interface utilisateur dans le niveau de données, simplifiez les choses en fusionnant le tout en une seule couche.

Certaines éditions de Visual Studio rencontrent des problèmes de performances dans environ 15 assemblys, cela dépend parfois du type de projet. Le déchargement stratégique des fichiers de projet peut parfois aider.

MatthewMartin
la source
Je suis le seul développeur de l'entreprise en ce moment. Et aussi fraîchement sorti de l'université, essayant ainsi d'inculquer de bonnes pratiques, sur les plus grands projets dès que possible. Je suis intéressé à le rendre maintenable parce que les spécifications du système ont tellement changé avant même que je commence à le documenter, contre les demandes de vouloir le système dès que possible. À votre avis, un assemblage ne contenant que des interfaces serait-il une solution appropriée? De cette façon, la dépendance ne devrait concerner que les interfaces et les classes d'usine.
JonWillis
1
Oui. Il est préférable de comprendre la motivation du fractionnement de l'assemblage, mais si vous (ou les membres de votre équipe) ne le faites pas, c'est toujours une manœuvre peu coûteuse. Donc, même si vous vous retrouvez avec tous les assemblys dépendant de tous les assemblys et sans espoir de tests unitaires, déplacer des choses qui se comportent comme des contrats (interfaces, classes abstraites) vers leur propre assemblage, est un pas dans la bonne direction et présente peu d'inconvénients.
MatthewMartin
-2

La seule bonne raison d'avoir plus d'un projet, c'est si vous devez partager un ensemble de classes et de fichiers entre plusieurs applications.

Si les projets sont utilisés par une seule application, ils n'auraient pas dû être créés en premier lieu. Utilisez plutôt des espaces de noms. Épargnez-vous le problème des références circulaires, des frais généraux des DLL et de la confusion du projet lors de la recherche de fichiers.

Lisez cet article pour une meilleure explication plus approfondie de la raison: http://lostechies.com/chadmyers/2008/07/16/project-anti-pattern-many-projects-in-a-visual-studio- fichier-solution /

Et comme l'indique l'article, j'accueillerais toute personne ayant une raison valable d'avoir plusieurs projets en dehors du partage de code entre les applications pour me dire de quoi il s'agit, car je doute qu'il y en ait.

Didier A.
la source
Des contre-arguments sur le downvote seraient appréciés.
Didier A.