Nous avons une solution avec plus de 100 projets, la plupart en C #. Naturellement, il faut beaucoup de temps à la fois pour ouvrir et construire, donc je recherche les meilleures pratiques pour ces bêtes. Les questions auxquelles j'espère obtenir des réponses sont les suivantes:
- comment gérer au mieux les références entre les projets
- "Copier local" doit-il être activé ou désactivé?
chaque projet doit-il être construit dans son propre dossier, ou doit-il tous construire 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 diviser la solution en plusieurs solutions plus petites est une option, mais cela vient avec son propre ensemble de refactoring et de création de maux de tête, alors peut-être pouvons-nous l'enregistrer pour un thread séparé :-)
Réponses:
Vous pourriez être intéressé par ces deux articles MSBuild que j'ai écrits.
MSBuild: Meilleures pratiques pour créer des builds fiables, partie 1
MSBuild: Meilleures pratiques pour la création de builds fiables, partie 2
Spécifiquement dans la partie 2, il y a une section Construire de grandes arborescences de sources que vous voudrez peut-être jeter un coup d'œil.
Pour répondre brièvement à vos questions ici:
Sayed Ibrahim Hashimi
Mon livre: dans le moteur de construction Microsoft: utilisation de MSBuild et Team Foundation Build
la source
+1 pour une utilisation économe 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 et cela peut conduire à des références subtiles et pénibles à 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é que svn: externals fonctionne bien pour les assemblys internes tiers et (de type framework). Prenez simplement 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 chargé :)
la source
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 à ouvrir / fermer / construire.
la source
Nous avons un problème similaire car nous avons 109 projets distincts à traiter. Pour répondre aux questions originales en fonction de nos expériences:
1. Comment gérer au 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 par défaut à notre fichier de solution global unique.
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.
3. Chaque projet doit-il être généré dans son propre dossier ou doit-il tous être généré dans le même dossier de sortie (ils font tous partie de la même application)
Toutes nos sorties sont placées dans un seul dossier 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 du 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 nécessaire pour trouver quoi que ce soit. Nous avons une structure complètement plate mais nommons nos fichiers de projet, nos assemblages et nos espaces de noms de la même manière.
Notre façon de structurer les projets repose sur un seul fichier solution. Construire cela prend beaucoup de temps, même si les projets eux-mêmes n'ont pas changé. Pour vous aider, 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 les projets qui ne sont pas dans l'ensemble actuel.
Un exemple partiel de notre disposition de 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]
la source
Nous travaillons ici sur un grand projet similaire. Les dossiers de solutions se sont avérés être un bon moyen d'organiser les choses, et nous avons tendance à laisser la copie locale sur true. Chaque projet se construit dans son propre dossier, puis nous savons que pour chaque projet déployable, nous avons le sous-ensemble correct des binaires en place.
En ce qui concerne l'ouverture du temps et la construction du temps, cela va être difficile à résoudre sans se casser en solutions plus petites. Vous pouvez étudier la mise en parallèle de la construction (google "Parallel MS Build" pour un moyen de le faire et de l'intégrer dans l'interface utilisateur) pour améliorer la vitesse ici. En outre, regardez la conception et voyez si la refactorisation de certains de vos projets pour en réduire globalement peut aider.
la source
En termes de facilité de construction, vous pouvez utiliser l'option "Configuration Manager ..." pour les builds afin d'activer ou de 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 plus de 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 pour accélérer le temps de chargement (et utilisation de la mémoire) de devenv.
la source
Ce que je fais généralement avec cela dépend un peu de la façon dont le processus de "débogage" se déroule réellement. En règle générale, je ne règle PAS la copie locale sur true. J'ai configuré le répertoire de construction pour chaque projet pour tout afficher au point final souhaité.
Par conséquent, après chaque build, 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 puisque la DLL finit par se retrouver au bon endroit.
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!
la source
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. là-dessus 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 qui les intéressent, les développeurs de services et les développeurs d'interface utilisateur la même chose. Il est rare que quelqu'un doive ouvrir toute la solution pour faire ce dont il a besoin au jour le jour. Ce n'est pas une panacée - il a ses avantages et ses inconvénients. Voir "modèle multi-solution" dans cet article (ignorez la partie sur l'utilisation de VSS :)
la source
Je pense qu'avec des solutions de cette envergure, la meilleure pratique devrait être de les briser. Vous pouvez penser à la «solution» comme un lieu pour rassembler les projets nécessaires et peut-être d'autres pièces pour travailler sur une solution à un problème. En divisant les plus de 100 projets en plusieurs solutions spécialisées dans le développement de solutions pour une partie seulement du problème global, vous pouvez en traiter moins à un moment donné en accélérant vos interactions avec les projets requis et en simplifiant le domaine du problème.
Chaque solution produirait le résultat 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 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 bonne 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.
la source
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 était toujours 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 source.
Tous les projets de bibliothèque de classes seraient 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 plutôt une référence basée sur un fichier du dossier CommonBin. J'ai écrit une tâche MSBuild personnalisée qui inspecterait les projets et déterminerait l'ordre de construction.
Nous l'utilisons depuis quelques années maintenant et nous n'avons rien à redire.
la source
Tout est lié à votre définition et à votre vision de ce que sont une solution et un projet. Dans mon esprit, une solution n'est que cela, un regroupement logique de projets qui résolvent une exigence très spécifique. Nous développons une grande application Intranet. Chaque application de cet intranet a sa propre solution, qui peut également contenir des projets pour les services exes ou Windows. Et puis nous avons un framework centralisé avec des choses comme les classes de base et les helpers et httphandlers / httpmodules. Le framework de base est assez volumineux et est utilisé par toutes les applications. En répartissant ainsi les nombreuses solutions, 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 est avec les références de projet, elles peuvent vraiment vous foutre en l'air, 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 d'Enterprise Library si vous voulez). Vous pouvez soit le partager en GAC, soit référencer directement l'emplacement du fichier afin d'avoir un magasin central. Vous pouvez également utiliser la même tactique pour les objets métier centralisés.
Si vous souhaitez référencer directement la DLL, vous voudrez la référencer dans votre projet avec une copie locale false (quelque part comme c: \ mycompany \ bin \ mycompany.dll). Un environnement d'exécution, vous devrez 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 si c'est une copie locale ou non, ou si la dll se retrouve dans la corbeille ou est même dans le GAC, car la configuration remplacera les deux. Je pense que c'est une mauvaise pratique de copier localement et d'avoir un système en désordre. Vous devrez probablement copier localement temporairement si vous avez besoin de déboguer dans l'un de ces assemblys.
Vous pouvez lire mon article sur la façon d'utiliser une 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 de redémarrage automatique sur les applications.
http://nbaked.wordpress.com/2010/03/28/gac-alternative/
la source
Définir CopyLocal = false réduira le temps de génération, mais peut entraîner différents problèmes pendant le déploiement.
Il existe de nombreux scénarios, lorsque vous avez besoin de laisser Copy Local 'sur True, par exemple les projets de niveau supérieur, les dépendances de second niveau, les 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 pas modifier les références de projet" Copier local "en false, à moins de comprendre les sous-séquences.
la source