web-dev-qa-db-fra.com

Meilleures pratiques pour les grandes solutions dans Visual Studio (2008)

Nous avons une solution avec environ 100+ projets, la plupart d'entre eux C #. Naturellement, il faut beaucoup de temps pour ouvrir et construire, donc je recherche des meilleures pratiques pour de telles bêtes. Le long des lignes de questions que j'espère obtenir des réponses, sont:

  • comment gérez-vous le mieux les références entre les projets
    • la "copie locale" doit-elle être activée ou désactivée?
  • chaque projet doit-il être construit dans son propre dossier, ou doit-il tous être construit dans le même dossier de sortie (ils font tous partie de la même application)

  • Les dossiers de solutions sont-ils un bon moyen d'organiser les choses?

Je sais que le fractionnement de la solution en plusieurs solutions plus petites est une option, mais cela vient avec son propre ensemble de refactoring et de construction de maux de tête, donc peut-être pouvons-nous enregistrer cela pour un thread séparé :-)

85
Eyvind

Vous pourriez être intéressé par ces deux articles MSBuild que j'ai écrits.

MSBuild: Meilleures pratiques pour créer des versions fiables, partie 1

MSBuild: Meilleures pratiques pour créer des builds fiables, partie 2

Spécifiquement dans la partie 2, il y a une section Construire de grands arbres sources que vous voudrez peut-être regarder.

Pour répondre brièvement à vos questions ici cependant:

  • CopyLocal? Bien sûr, désactivez-le
  • Construire dans un ou plusieurs dossiers de sortie? Construire dans un dossier de sortie
  • Dossiers de solutions? C'est une question de goût.

Sayed Ibrahim Hashimi

Mon livre: à l'intérieur du moteur de génération Microsoft: utilisation de MSBuild et de Team Foundation Build

41

+1 pour épargnant utilisation des dossiers de solutions pour aider à organiser les choses.

+1 pour la construction du projet dans son propre dossier. Nous avons d'abord essayé un dossier de sortie commun, ce qui peut conduire à des références subtiles et difficiles à trouver.

FWIW, nous utilisons des références de projet pour les solutions, et bien que nuget soit probablement un meilleur choix de nos jours, nous avons trouvé svn: externals pour bien fonctionner à la fois pour les assemblages internes tiers et (type de cadre). Prenez l'habitude d'utiliser un numéro de révision spécifique au lieu de HEAD lorsque vous faites référence à svn: externals (coupable comme accusé :)

9
si618

Déchargez les projets que vous n'utilisez pas souvent et achetez un SSD. Un SSD n'améliore pas le temps de compilation, mais Visual Studio devient deux fois plus rapide pour ouvrir/fermer/construire.

8
Nicolas Dorier

Nous avons un problème similaire car nous avons 109 projets distincts à traiter. Pour répondre aux questions originales basées sur nos expériences:

1. Comment gérez-vous le mieux les références entre les projets

Nous utilisons l'option de menu contextuel "ajouter une référence". Si "projet" est sélectionné, la dépendance est ajoutée à notre fichier de solution global unique par défaut.

2. La "copie locale" doit-elle être activée ou désactivée?

Off dans notre expérience. La copie supplémentaire ne fait qu'ajouter aux temps de construction.

. Chaque projet doit-il être construit dans son propre dossier, ou doit-il tous être construit dans le même dossier de sortie (ils font tous partie de la même application)

Toutes nos sorties sont placées dans un dossier unique appelé "bin". L'idée étant que ce dossier est le même que lorsque le logiciel est déployé. Cela permet d'éviter les problèmes qui se produisent lorsque la configuration du développeur est différente de la configuration de déploiement.

4. Les dossiers de solutions sont-ils un bon moyen d'organiser les choses?

Non dans notre expérience. La structure des dossiers d'une personne est le cauchemar d'une autre. Les dossiers profondément imbriqués augmentent simplement le temps qu'il faut pour trouver quoi que ce soit. Nous avons une structure complètement plate, mais nommez nos fichiers de projet, assemblys et espaces de noms de la même manière.


Notre façon de structurer les projets repose sur un seul fichier de solution. Construire cela prend beaucoup de temps, même si les projets eux-mêmes n'ont pas changé. Pour aider à cela, nous créons généralement un autre fichier de solution "ensemble de travail actuel". Tous les projets sur lesquels nous travaillons sont ajoutés à cela. Les temps de construction sont considérablement améliorés, bien qu'un problème que nous ayons vu est qu'Intellisense échoue pour les types définis dans des projets qui ne sont pas dans l'ensemble actuel.

Un exemple partiel de la disposition de notre solution:

\bin

OurStuff.SLN

OurStuff.App.Administrator
OurStuff.App.Common
OurStuff.App.Installer.Database
OurStuff.App.MediaPlayer
OurStuff.App.Operator
OurStuff.App.Service.Gateway
OurStuff.App.Service.CollectionStation
OurStuff.App.ServiceLocalLauncher
OurStuff.App.StackTester
OurStuff.Auditing
OurStuff.Data
OurStuff.Database
OurStuff.Database.Constants
OurStuff.Database.ObjectModel
OurStuff.Device
OurStuff.Device.Messaging
OurStuff.Diagnostics
...
[etc]
6
Thomas Bratt

Nous travaillons sur un grand projet similaire ici. Les dossiers de solutions se sont révélés être un bon moyen d'organiser les choses, et nous avons tendance à laisser la copie locale à true. Chaque projet est construit dans son propre dossier, puis nous savons que pour chaque projet déployable, nous avons en place le sous-ensemble correct des fichiers binaires.

Quant à l'ouverture et à la construction du temps, cela va être difficile à résoudre sans se diviser en solutions plus petites. Vous pouvez étudier la parallélisation de la construction (google "Parallel MS Build" pour un moyen de le faire et l'intégration dans l'interface utilisateur) pour améliorer la vitesse ici. En outre, examinez la conception et voyez si la refactorisation de certains de vos projets pour réduire le nombre global pourrait aider.

4
David M

Nous avons un problème similaire. Nous le résolvons en utilisant des solutions plus petites. Nous avons une solution principale qui ouvre tout. Mais perf. c'est mauvais. Nous segmentons donc les solutions plus petites par type de développeur. Ainsi, les développeurs de bases de données ont une solution qui charge les projets dont ils se soucient, les développeurs de services et les développeurs d'interfaces utilisateur la même chose. Il est rare que quelqu'un doive ouvrir toute la solution pour obtenir ce dont il a besoin au quotidien. Ce n'est pas une panacée - elle a ses avantages et ses inconvénients. Voir "modèle multi-solution" dans cet article (ignorez la partie sur l'utilisation de VSS :)

3
JP Alioto

En termes de soulagement de la douleur de construction, vous pouvez utiliser l'option "Configuration Manager ..." pour les builds pour activer ou désactiver la construction de projets spécifiques. Vous pouvez avoir un "Projet [n] Build" qui pourrait exclure certains projets et l'utiliser lorsque vous ciblez des projets spécifiques.

En ce qui concerne les 100+ projets, je sais que vous ne voulez pas être martelé dans cette question sur les avantages de réduire la taille de votre solution, mais je pense que vous n'avez pas d'autre option en ce qui concerne l'accélération du temps de chargement (et utilisation de la mémoire) de devenv.

3
Michael Meadows

Ce que je fais généralement avec cela dépend un peu de la façon dont le processus de "débogage" se produit réellement. En règle générale, bien que je ne définisse PAS la copie locale comme vraie. J'ai configuré le répertoire de construction pour chaque projet pour tout sortir au point final souhaité.

Par conséquent, après chaque génération, j'ai un dossier rempli avec toutes les DLL et toutes les applications Windows/Web et tous les éléments sont au bon endroit. La copie locale n'était pas nécessaire car la fin de la DLL est au bon endroit à la fin.

Remarque

Ce qui précède fonctionne pour mes solutions, qui sont généralement des applications Web et je n'ai rencontré aucun problème avec les références, mais cela pourrait être possible!

3
Mitchel Sellers

Nous avons environ 60 projets et nous n'utilisons pas de fichiers de solution. Nous avons un mélange de projets C # et VB.Net. La performance a toujours été un problème. Nous ne travaillons pas sur tous les projets en même temps. Chaque développeur crée ses propres fichiers de solution en fonction des projets sur lesquels il travaille. Les fichiers de solution ne sont pas archivés dans notre contrôle de code source.

Tous les projets de bibliothèque de classes seront générés dans un dossier CommonBin à la racine du répertoire source. Les projets exécutables/Web sont créés dans leur dossier individuel.

Nous n'utilisons pas de références de projet, mais des références basées sur des fichiers à partir du dossier CommonBin. J'ai écrit une tâche MSBuild personnalisée qui inspecterait les projets et déterminerait l'ordre de génération.

Nous utilisons cela depuis quelques années maintenant et nous n'avons aucune plainte.

2

Je pense qu'avec des solutions aussi importantes, la meilleure pratique devrait être de les casser. Vous pouvez penser à la "solution" comme un lieu pour rassembler les projets nécessaires et peut-être d'autres éléments pour travailler sur une solution à un problème. En divisant les 100+ projets en plusieurs solutions spécialisées dans le développement de solutions pour une partie seulement du problème global, vous pouvez y faire face à un moment donné en accélérant vos interactions avec les projets requis et en simplifiant le domaine du problème.

Chaque solution produirait la sortie dont elle est responsable. Cette sortie doit avoir des informations de version qui peuvent être définies dans un processus automatisé. Lorsque la sortie est stable, vous pouvez mettre à jour les références dans les projets et solutions dépendants avec la dernière distribution interne. Si vous souhaitez toujours entrer dans le code et accéder à la source, vous pouvez réellement le faire avec le serveur de symboles Microsoft que Visual Studio peut utiliser pour vous permettre d'accéder aux assemblys référencés et même d'extraire le code source.

Le développement simultané peut être effectué en spécifiant les interfaces à l'avance et en se moquant des assemblys en cours de développement pendant que vous attendez des dépendances qui ne sont pas complètes mais que vous souhaitez développer.

Je trouve que c'est une meilleure pratique car il n'y a pas de limite à la complexité de l'effort global lorsque vous le décomposez physiquement de cette manière. Mettre tous les projets dans une seule solution atteindra finalement une limite supérieure.

J'espère que cette information vous aidera.

2
Blake Taylor

Définissez CopyLocal = false réduira le temps de génération, mais peut entraîner différents problèmes pendant le temps de déploiement.

Il existe de nombreux scénarios, lorsque vous devez laisser Copy Local ’à True, par exemple Projets de niveau supérieur, dépendances de second niveau, DLL appelées par réflexion.

Mon expérience avec la définition de CopyLocal = false n'a pas réussi. Voir le résumé des avantages et des inconvénients dans mon article de blog "Ne changez pas les références du projet" Copier local "en faux, sauf si vous comprenez les sous-séquences."

0
Michael Freidgeim

Tout cela a à voir avec votre définition et votre vision de ce qu'est une solution et un projet. Dans mon esprit, une solution n'est que cela, un regroupement logique de projets qui répondent à une exigence très spécifique. Nous développons une grande application Intranet. Chaque application de cet intranet possède sa propre solution, qui peut également contenir des projets d'exes ou de services Windows. Et puis nous avons un cadre centralisé avec des choses comme les classes de base et les assistants et httphandlers/httpmodules. Le cadre de base est assez grand et est utilisé par toutes les applications. En répartissant les nombreuses solutions de cette manière, vous réduisez le nombre de projets requis par une solution, car la plupart d'entre eux n'ont rien à voir les uns avec les autres.

Avoir autant de projets dans une solution est tout simplement une mauvaise conception. Il ne devrait y avoir aucune raison d'avoir autant de projets sous une solution. L'autre problème que je vois concerne les références de projet, elles peuvent vraiment vous gâcher éventuellement, surtout si vous souhaitez diviser votre solution en plus petites.

Mon conseil est de le faire et de développer un cadre centralisé (votre propre implémentation de Enterprise Library si vous voulez). Vous pouvez soit le GAC à partager ou vous pouvez référencer directement l'emplacement du fichier afin que vous ayez un magasin central. Vous pouvez également utiliser la même tactique pour les objets métier centralisés.

Si vous voulez référencer directement le DLL vous voudrez le référencer dans votre projet avec la copie locale false (quelque part comme c:\mycompany\bin\mycompany.dll). Un runtime dont vous aurez besoin pour ajouter des paramètres à votre app.config ou web.config pour qu'il fasse référence à un fichier qui ne se trouve pas dans le GAC ou le bac d'exécution. En réalité, peu importe qu'il s'agisse d'une copie locale ou non, ou si la DLL se retrouve dans bin ou est même dans le GAC, car la configuration remplacera les deux. Je pense que c'est une mauvaise pratique de copier local et d'avoir un système en désordre. Vous devrez très probablement copier localement temporairement si vous avez besoin de déboguer dans l'un de ces assemblées cependant.

Vous pouvez lire mon article sur la façon d'utiliser un DLL globalement sans le GAC. Je n'aime vraiment pas le GAC principalement parce qu'il empêche le déploiement de xcopy et ne déclenche pas un redémarrage automatique sur les applications.

http://nbaked.wordpress.com/2010/03/28/gac-alternative/

0
user306031