Wir haben eine Lösung mit über 100 Projekten, die meisten davon C #. Natürlich dauert das Öffnen und Bauen sehr lange, daher suche ich nach Best Practices für solche Bestien. In Bezug auf die Fragen, auf die ich Antworten erhoffe, sind:
- Wie gehen Sie am besten mit Referenzen zwischen Projekten um?
- sollte "copy local" ein- oder ausgeschaltet sein?
sollte jedes Projekt in einem eigenen Ordner erstellt werden oder sollten alle in demselben Ausgabeordner erstellt werden (sie sind alle Teil derselben Anwendung)
Sind die Ordner von Lösungen eine gute Möglichkeit, Dinge zu organisieren?
Ich weiß, dass es eine Option ist, die Lösung in mehrere kleinere Lösungen aufzuteilen, aber das bringt eine Reihe von Umgestaltungen und Kopfschmerzen mit sich. Vielleicht können wir das für einen separaten Thread speichern :-)
Antworten:
Diese beiden MSBuild-Artikel, die ich geschrieben habe, könnten Sie interessieren.
MSBuild: Best Practices zum Erstellen zuverlässiger Builds, Teil 1
MSBuild: Best Practices zum Erstellen zuverlässiger Builds, Teil 2
Insbesondere in Teil 2 gibt es einen Abschnitt Erstellen großer Quellbäume , den Sie sich ansehen möchten.
Um Ihre Fragen hier kurz zu beantworten:
Sagte Ibrahim Hashimi
Mein Buch: In der Microsoft Build Engine: Verwenden von MSBuild und Team Foundation Build
quelle
+1 für die sparsame Verwendung von Lösungsordnern zur Organisation von Aufgaben.
+1 für die Projekterstellung in einem eigenen Ordner. Wir haben zunächst einen gemeinsamen Ausgabeordner ausprobiert. Dies kann dazu führen, dass subtile und schmerzhafte veraltete Referenzen gefunden werden.
FWIW, wir verwenden Projektreferenzen für Lösungen, und obwohl Nuget heutzutage wahrscheinlich die bessere Wahl ist, haben wir festgestellt, dass svn: externals sowohl für interne Assemblys von Drittanbietern als auch für (Assembly-Typ-) interne Assemblys gut funktioniert. Gewöhnen Sie sich einfach an, eine bestimmte Revisionsnummer anstelle von HEAD zu verwenden, wenn Sie auf svn: externals verweisen (schuldig wie angeklagt :)
quelle
Entladen Sie Projekte, die Sie nicht oft verwenden, und kaufen Sie eine SSD. Eine SSD verbessert die Kompilierungszeit nicht, aber Visual Studio lässt sich zweimal schneller öffnen / schließen / erstellen.
quelle
Wir haben ein ähnliches Problem wie 109 separate Projekte. Um die ursprünglichen Fragen zu beantworten, die auf unseren Erfahrungen basieren:
1. Wie gehen Sie am besten mit Referenzen zwischen Projekten um?
Wir verwenden die Kontextmenüoption 'Referenz hinzufügen'. Wenn 'Projekt' ausgewählt ist, wird die Abhängigkeit standardmäßig zu unserer einzelnen globalen Lösungsdatei hinzugefügt.
2. Sollte "copy local" ein- oder ausgeschaltet sein?
Aus unserer Erfahrung. Das zusätzliche Kopieren verlängert nur die Erstellungszeiten.
3. Sollte jedes Projekt in einem eigenen Ordner erstellt werden oder sollten alle in demselben Ausgabeordner erstellt werden (sie sind alle Teil derselben Anwendung)?
Alle unsere Ausgaben werden in einem einzigen Ordner namens 'bin' abgelegt. Die Idee ist, dass dieser Ordner derselbe ist wie bei der Bereitstellung der Software. Dies hilft, Probleme zu vermeiden, die auftreten, wenn sich das Entwickler-Setup vom Bereitstellungs-Setup unterscheidet.
4. Sind Lösungsordner eine gute Möglichkeit, Dinge zu organisieren?
Nein nach unserer Erfahrung. Die Ordnerstruktur einer Person ist der Albtraum einer anderen Person. Tief verschachtelte Ordner verlängern nur die Zeit, die benötigt wird, um etwas zu finden. Wir haben eine völlig flache Struktur, aber benennen unsere Projektdateien, Assemblys und Namespaces gleich.
Unsere Art, Projekte zu strukturieren, basiert auf einer einzigen Lösungsdatei. Der Aufbau dauert lange, auch wenn sich die Projekte selbst nicht geändert haben. Um dies zu unterstützen, erstellen wir normalerweise eine andere Lösungsdatei für den aktuellen Arbeitssatz. Alle Projekte, an denen wir arbeiten, werden hinzugefügt. Die Erstellungszeiten werden erheblich verbessert, obwohl ein Problem darin besteht, dass Intellisense für Typen fehlschlägt, die in Projekten definiert sind, die nicht im aktuellen Satz enthalten sind.
Ein Teilbeispiel unseres Lösungslayouts:
quelle
Wir arbeiten hier an einem ähnlich großen Projekt. Lösungsordner haben sich als eine gute Möglichkeit zum Organisieren von Dingen erwiesen, und wir neigen dazu, die lokale Kopie einfach auf true zu setzen. Jedes Projekt wird in einem eigenen Ordner erstellt, und dann wissen wir, dass für jedes bereitstellbare Projekt dort die richtige Teilmenge der Binärdateien vorhanden ist.
Die Zeiteröffnung und der Zeitaufbau werden schwer zu beheben sein, ohne in kleinere Lösungen einzudringen. Sie können die Parallelisierung des Builds untersuchen (Google "Parallel MS Build", um dies zu tun und in die Benutzeroberfläche zu integrieren), um hier die Geschwindigkeit zu verbessern. Sehen Sie sich auch das Design an und prüfen Sie, ob eine Umgestaltung einiger Ihrer Projekte, die insgesamt zu weniger führt, hilfreich sein kann.
quelle
Um die Schmerzen beim Erstellen zu lindern, können Sie die Option "Configuration Manager ..." für Builds verwenden, um das Erstellen bestimmter Projekte zu aktivieren oder zu deaktivieren. Sie können ein "Project [n] Build" erstellen, das bestimmte Projekte ausschließen und dieses verwenden kann, wenn Sie auf bestimmte Projekte abzielen.
Was die über 100 Projekte angeht, weiß ich, dass Sie sich nicht mit dieser Frage über die Vorteile einer Reduzierung Ihrer Lösungsgröße beschäftigen möchten, aber ich denke, Sie haben keine andere Möglichkeit, die Ladezeit zu beschleunigen (und Speichernutzung) von devenv.
quelle
Was ich normalerweise damit mache, hängt ein wenig davon ab, wie der "Debug" -Prozess tatsächlich abläuft. Normalerweise setze ich die lokale Kopie jedoch NICHT auf true. Ich habe das Build-Verzeichnis für jedes Projekt so eingerichtet, dass alles an den gewünschten Endpunkt ausgegeben wird.
Daher habe ich nach jedem Build einen Ordner mit allen DLLs und allen Windows- / Webanwendungen, und alle Elemente befinden sich am richtigen Speicherort. Lokale Kopie wurde nicht benötigt, da die DLL am Ende an der richtigen Stelle landet.
Hinweis
Das Obige funktioniert für meine Lösungen, bei denen es sich normalerweise um Webanwendungen handelt, und ich habe keine Probleme mit Referenzen festgestellt, aber es ist möglicherweise möglich!
quelle
Wir haben ein ähnliches Problem. Wir lösen es mit kleineren Lösungen. Wir haben eine Master-Lösung, die alles öffnet. Aber perf. darauf ist schlecht. Daher segmentieren wir kleinere Lösungen nach Entwicklertyp. DB-Entwickler haben also eine Lösung, die die Projekte lädt, die sie interessieren, Service-Entwickler und UI-Entwickler das Gleiche. Es kommt selten vor, dass jemand die gesamte Lösung öffnen muss, um täglich das zu erledigen, was er benötigt. Es ist kein Allheilmittel - es hat seine Vor- und Nachteile. Siehe "Multi-Solution-Modell" in diesem Artikel (ignorieren Sie den Teil über die Verwendung von VSS :)
quelle
Ich denke, bei so großen Lösungen sollte die beste Vorgehensweise darin bestehen, sie aufzubrechen. Sie können sich die "Lösung" als einen Ort vorstellen, an dem Sie die erforderlichen Projekte und möglicherweise andere Teile zusammenführen können, um an einer Lösung für ein Problem zu arbeiten. Indem Sie die über 100 Projekte in mehrere Lösungen aufteilen, die darauf spezialisiert sind, Lösungen für nur einen Teil des Gesamtproblems zu entwickeln, können Sie dort zu einem bestimmten Zeitpunkt weniger Probleme lösen, indem Sie Ihre Interaktionen mit den erforderlichen Projekten beschleunigen und die Problemdomäne vereinfachen.
Jede Lösung würde die Ausgabe erzeugen, für die sie verantwortlich ist. Diese Ausgabe sollte Versionsinformationen enthalten, die in einem automatisierten Prozess festgelegt werden können. Wenn die Ausgabe stabil ist, können Sie die Referenzen in abhängigen Projekten und Lösungen mit der neuesten internen Verteilung aktualisieren. Wenn Sie dennoch in den Code eintreten und auf die Quelle zugreifen möchten, können Sie dies tatsächlich mit dem Microsoft-Symbolserver tun, mit dem Visual Studio in referenzierte Assemblys zugreifen und sogar den Quellcode abrufen kann.
Die gleichzeitige Entwicklung kann erfolgen, indem Schnittstellen im Voraus angegeben und die in der Entwicklung befindlichen Assemblys verspottet werden, während Sie auf Abhängigkeiten warten, die nicht vollständig sind, gegen die Sie jedoch entwickeln möchten.
Ich halte dies für eine bewährte Methode, da die Komplexität des Gesamtaufwands unbegrenzt ist, wenn Sie ihn auf diese Weise physisch aufteilen. Wenn Sie alle Projekte in einer einzigen Lösung zusammenfassen, wird dies letztendlich eine Obergrenze erreichen.
Hoffe, diese Informationen helfen.
quelle
Wir haben über 60 Projekte und verwenden keine Lösungsdateien. Wir haben eine Mischung aus C # - und VB.Net-Projekten. Die Leistung war immer ein Thema. Wir arbeiten nicht an allen Projekten gleichzeitig. Jeder Entwickler erstellt seine eigenen Lösungsdateien basierend auf den Projekten, an denen er arbeitet. Die Lösungsdateien werden nicht in unsere Quellcodeverwaltung eingecheckt.
Alle Klassenbibliotheksprojekte werden in einem CommonBin-Ordner im Stammverzeichnis des Quellverzeichnisses erstellt. Ausführbare / Web-Projekte werden in ihren jeweiligen Ordner erstellt.
Wir verwenden keine Projektreferenzen, sondern dateibasierte Referenzen aus dem CommonBin-Ordner. Ich habe eine benutzerdefinierte MSBuild-Aufgabe geschrieben, die die Projekte überprüft und die Erstellungsreihenfolge bestimmt.
Wir verwenden dies seit einigen Jahren und haben keine Beschwerden.
quelle
Alles hängt mit Ihrer Definition und Ihrer Sicht auf eine Lösung und ein Projekt zusammen. In meinen Augen ist eine Lösung genau das, eine logische Gruppierung von Projekten, die eine ganz bestimmte Anforderung lösen. Wir entwickeln eine große Intranet-Anwendung. Jede Anwendung in diesem Intranet verfügt über eine eigene Lösung, die auch Projekte für Exes oder Windows-Dienste enthalten kann. Und dann haben wir ein zentrales Framework mit Dingen wie Basisklassen und Helfern und httphandlers / httpmodules. Das Basisframework ist ziemlich groß und wird von allen Anwendungen verwendet. Indem Sie die vielen Lösungen auf diese Weise aufteilen, reduzieren Sie die Anzahl der Projekte, die für eine Lösung erforderlich sind, da die meisten von ihnen nichts miteinander zu tun haben.
So viele Projekte in einer Lösung zu haben, ist einfach schlechtes Design. Es sollte keinen Grund geben, so viele Projekte unter einer Lösung zu haben. Das andere Problem, das ich sehe, sind Projektreferenzen, die Sie letztendlich wirklich vermasseln können, insbesondere wenn Sie Ihre Lösung jemals in kleinere aufteilen möchten.
Mein Rat ist, dies zu tun und ein zentrales Framework zu entwickeln (Ihre eigene Implementierung der Enterprise Library, wenn Sie so wollen). Sie können entweder GAC für die Freigabe verwenden oder direkt auf den Speicherort der Datei verweisen, sodass Sie über einen zentralen Speicher verfügen. Sie können dieselbe Taktik auch für zentralisierte Geschäftsobjekte verwenden.
Wenn Sie direkt auf die DLL verweisen möchten, möchten Sie sie in Ihrem Projekt mit copy local false referenzieren (z. B. c: \ mycompany \ bin \ mycompany.dll). Zur Laufzeit müssen Sie Ihrer app.config oder web.config einige Einstellungen hinzufügen, damit sie auf eine Datei verweist, die sich nicht im GAC oder im Laufzeitbereich befindet. Tatsächlich spielt es keine Rolle, ob es sich um eine lokale Kopie handelt oder nicht oder ob die DLL im Bin oder sogar im GAC landet, da die Konfiguration beide überschreibt. Ich denke, es ist eine schlechte Praxis, lokal zu kopieren und ein chaotisches System zu haben. Sie müssen höchstwahrscheinlich vorübergehend lokal kopieren, wenn Sie in einer dieser Assemblys debuggen müssen.
Sie können meinen Artikel über die globale Verwendung einer DLL ohne GAC lesen. Ich mag den GAC wirklich nicht, vor allem, weil er die Bereitstellung von xcopy verhindert und keinen Autorestart für Anwendungen auslöst.
http://nbaked.wordpress.com/2010/03/28/gac-alternative/
quelle
Wenn Sie CopyLocal = false festlegen, wird die Erstellungszeit verkürzt, es können jedoch während der Bereitstellungszeit unterschiedliche Probleme auftreten.
Es gibt viele Szenarien, in denen Copy Local auf True gesetzt werden muss, z. B. Projekte der obersten Ebene, Abhängigkeiten der zweiten Ebene und DLLs, die durch Reflektion aufgerufen werden.
Meine Erfahrung mit dem Setzen von CopyLocal = false war nicht erfolgreich. Siehe Zusammenfassung der Vor- und Nachteile in meinem Blog-Beitrag "Ändern Sie NICHT" Lokale Projektreferenzen kopieren auf falsch, es sei denn, Sie verstehen Teilfolgen. "
quelle