Mamy rozwiązanie z ponad 100 projektami, większość z nich C #. Oczywiście zarówno otwieranie, jak i budowanie zajmuje dużo czasu, dlatego szukam najlepszych praktyk dla takich bestii. Wśród pytań, na które mam nadzieję uzyskać odpowiedzi, są:
- jak najlepiej radzić sobie z odwołaniami między projektami
- czy „kopiuj lokalnie” powinno być włączone czy wyłączone?
czy każdy projekt powinien być kompilowany do własnego folderu, czy też wszystkie powinny być kompilowane do tego samego folderu wyjściowego (wszystkie są częścią tej samej aplikacji)
Czy foldery rozwiązań to dobry sposób na porządkowanie rzeczy?
Wiem, że podzielenie rozwiązania na wiele mniejszych jest opcją, ale wiąże się to z własnym zestawem refaktoryzacji i problemów związanych z budowaniem, więc może możemy to zapisać na osobny wątek :-)
Odpowiedzi:
Możesz być zainteresowany tymi dwoma artykułami MSBuild, które napisałem.
MSBuild: najlepsze praktyki tworzenia niezawodnych kompilacji, część 1
MSBuild: najlepsze praktyki tworzenia niezawodnych kompilacji, część 2
W szczególności w części 2 znajduje się sekcja Budowanie dużych drzew źródłowych , której warto się przyjrzeć.
Aby jednak krótko odpowiedzieć na pytania tutaj:
Sayed Ibrahim Hashimi
Moja książka: Inside the Microsoft Build Engine: Korzystanie z MSBuild i Team Foundation Build
źródło
+1 za oszczędne korzystanie z folderów rozwiązań, które ułatwiają porządkowanie rzeczy.
+1 za tworzenie projektu do własnego folderu. Początkowo próbowaliśmy wspólnego folderu wyjściowego, co może prowadzić do subtelnych i bolesnych znalezienia nieaktualnych odniesień.
FWIW, używamy referencji projektowych do rozwiązań i chociaż nuget jest obecnie prawdopodobnie lepszym wyborem, odkryliśmy, że svn: externals działa dobrze zarówno w przypadku zespołów zewnętrznych, jak i wewnętrznych (typu framework). Po prostu nabądź nawyku używania określonego numeru wersji zamiast HEAD podczas odwoływania się do svn: externals (winny za opłatą :)
źródło
Zwolnij projekty, których nie używasz często, i kup dysk SSD. Dysk SSD nie skraca czasu kompilacji, ale program Visual Studio dwukrotnie szybciej otwiera / zamyka / kompiluje.
źródło
Mamy podobny problem, ponieważ mamy do rozwiązania 109 oddzielnych projektów. Aby odpowiedzieć na oryginalne pytania oparte na naszych doświadczeniach:
1. Jak najlepiej radzić sobie z odniesieniami między projektami
Używamy opcji menu kontekstowego „dodaj odniesienie”. W przypadku wybrania opcji „projekt” zależność zostanie dodana do naszego pojedynczego, globalnego pliku rozwiązania.
2. Czy „kopiuj lokalnie” powinno być włączone czy wyłączone?
Z naszego doświadczenia. Dodatkowe kopiowanie po prostu wydłuża czas kompilacji.
3. Czy każdy projekt powinien być kompilowany do własnego folderu, czy też wszystkie powinny budować do tego samego folderu wyjściowego (wszystkie są częścią tej samej aplikacji)
Wszystkie nasze wyniki są umieszczane w jednym folderze o nazwie „bin”. Chodzi o to, że ten folder jest taki sam, jak podczas wdrażania oprogramowania. Pomaga to uniknąć problemów, które występują, gdy konfiguracja dewelopera różni się od konfiguracji wdrożenia.
4. Czy foldery rozwiązań to dobry sposób na porządkowanie rzeczy?
Nie z naszego doświadczenia. Struktura folderów jednej osoby jest koszmarem innej osoby. Głęboko zagnieżdżone foldery tylko wydłużają czas potrzebny na znalezienie czegokolwiek. Mamy całkowicie płaską strukturę, ale tak samo nazywamy nasze pliki projektu, zestawy i przestrzenie nazw.
Nasz sposób tworzenia struktury projektów opiera się na jednym pliku rozwiązania. Budowa tego zajmuje dużo czasu, nawet jeśli same projekty się nie zmieniły. Aby w tym pomóc, zwykle tworzymy kolejny plik rozwiązania „aktualnego zestawu roboczego”. Wszelkie projekty, nad którymi pracujemy, są do tego dodawane. Czasy kompilacji uległy znacznej poprawie, chociaż jednym z problemów, które widzieliśmy, jest to, że Intellisense nie działa w przypadku typów zdefiniowanych w projektach, które nie znajdują się w bieżącym zestawie.
Częściowy przykład układu naszego rozwiązania:
\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]
źródło
Pracujemy tutaj nad podobnym dużym projektem. Foldery rozwiązań okazały się dobrym sposobem organizowania rzeczy i zwykle pozostawiamy ustawienie opcji kopiowania lokalnego na true. Każdy projekt jest kompilowany do własnego folderu, a następnie wiemy, że dla każdego projektu, który można wdrożyć, mamy w nim odpowiedni podzbiór plików binarnych.
Jeśli chodzi o czas otwierania i budowania czasu, będzie to trudne do naprawienia bez włamywania się do mniejszych rozwiązań. Możesz zbadać zrównoleglenie kompilacji (google „Parallel MS Build”, aby to zrobić i zintegrować z interfejsem użytkownika), aby poprawić tutaj szybkość. Przyjrzyj się również projektowi i zobacz, czy refaktoryzacja niektórych projektów w celu zmniejszenia ogólnej może pomóc.
źródło
Jeśli chodzi o złagodzenie problemów związanych z budowaniem, możesz użyć opcji „Menedżer konfiguracji…” dla kompilacji, aby włączyć lub wyłączyć tworzenie określonych projektów. Możesz mieć opcję „Projekt [n] Kompilacja”, która może wykluczać określone projekty i używać jej, gdy kierujesz reklamy na określone projekty.
Jeśli chodzi o ponad 100 projektów, wiem, że nie chcesz zostać wkurzony w to pytanie o korzyści płynące z zmniejszenia rozmiaru rozwiązania, ale myślę, że nie masz innej opcji, jeśli chodzi o przyspieszenie czasu ładowania (i wykorzystanie pamięci) programu devenv.
źródło
To, co zwykle z tym robię, zależy nieco od tego, jak faktycznie przebiega proces „debugowania”. Zazwyczaj jednak NIE ustawiam kopiowania lokalnego na true. Konfiguruję katalog kompilacji dla każdego projektu, aby wyprowadzić wszystko do żądanego punktu końcowego.
Dlatego po każdej kompilacji mam zapełniony folder ze wszystkimi bibliotekami dll i aplikacjami Windows / Web, a wszystkie elementy znajdują się we właściwej lokalizacji. Kopiowanie lokalne nie było potrzebne, ponieważ dll ostatecznie trafia we właściwe miejsce.
Uwaga
Powyższe działa dla moich rozwiązań, które zazwyczaj są aplikacjami internetowymi i nie miałem żadnych problemów z odwołaniami, ale może to być możliwe!
źródło
Mamy podobny problem. Rozwiązujemy to za pomocą mniejszych rozwiązań. Mamy mistrzowskie rozwiązanie, które otwiera wszystko. Ale perf. na tym jest źle. Dlatego dzielimy mniejsze rozwiązania według typu programisty. Tak więc programiści DB mają rozwiązanie, które ładuje projekty, na których im zależy, programiści usług i programiści UI to samo. Rzadko zdarza się, aby ktoś musiał otworzyć całe rozwiązanie, aby wykonać to, czego potrzebuje na co dzień. To nie jest panaceum - ma swoje wady i zalety. Zobacz „Model wielu rozwiązań” w tym artykule (zignoruj część dotyczącą korzystania z usługi VSS :)
źródło
Myślę, że przy tak dużych rozwiązaniach najlepszą praktyką powinno być ich rozbicie. Możesz myśleć o „rozwiązaniu” jako o miejscu, w którym zebrane zostaną niezbędne projekty i być może inne elementy do pracy nad rozwiązaniem problemu. Dzieląc ponad 100 projektów na wiele rozwiązań wyspecjalizowanych w opracowywaniu rozwiązań tylko dla części ogólnego problemu, możesz zająć się mniej w danym momencie, przyspieszając interakcje z wymaganymi projektami i upraszczając dziedzinę problemów.
Każde rozwiązanie dawałoby wynik, za który jest odpowiedzialne. Te dane wyjściowe powinny zawierać informacje o wersji, które można ustawić w zautomatyzowanym procesie. Gdy wynik jest stabilny, można zaktualizować odniesienia w zależnych projektach i rozwiązaniach za pomocą najnowszej dystrybucji wewnętrznej. Jeśli nadal chcesz wejść do kodu i uzyskać dostęp do źródła, możesz to zrobić za pomocą serwera symboli firmy Microsoft, którego program Visual Studio może użyć, aby umożliwić wejście do zestawów, do których istnieją odwołania, a nawet pobranie kodu źródłowego.
Równoczesne programowanie można wykonać, określając interfejsy z góry i mockując zestawy w trakcie opracowywania, gdy czekasz na zależności, które nie są kompletne, ale chcesz je opracować.
Uważam, że jest to najlepsza praktyka, ponieważ nie ma ograniczeń co do tego, jak złożony może być ogólny wysiłek, gdy rozbijesz go fizycznie w ten sposób. Umieszczenie wszystkich projektów w jednym rozwiązaniu ostatecznie osiągnie górny limit.
Mam nadzieję, że te informacje pomogą.
źródło
Mamy ponad 60 projektów i nie używamy plików rozwiązań. Mamy połączenie projektów C # i VB.Net. Wydajność zawsze była problemem. Nie pracujemy nad wszystkimi projektami jednocześnie. Każdy programista tworzy własne pliki rozwiązań na podstawie projektów, nad którymi pracuje. Pliki rozwiązania nie są wpisywane do naszej kontroli źródła.
Wszystkie projekty bibliotek klas byłyby kompilowane do folderu CommonBin w katalogu głównym katalogu źródłowego. Pliki wykonywalne / projekty internetowe są tworzone w ich indywidualnych folderach.
Nie używamy odwołań do projektów, zamiast tego odwołujemy się do plików z folderu CommonBin. Napisałem niestandardowe zadanie MSBuild, które będzie sprawdzać projekty i określać kolejność kompilacji.
Używamy tego od kilku lat i nie mamy żadnych skarg.
źródło
Wszystko to ma związek z twoją definicją i poglądem na to, czym jest rozwiązanie i projekt. Moim zdaniem rozwiązaniem jest po prostu logiczne pogrupowanie projektów, które rozwiązują bardzo specyficzne wymagania. Tworzymy dużą aplikację intranetową. Każda aplikacja w tym intranecie ma własne rozwiązanie, które może również zawierać projekty dla usług exes lub Windows. Następnie mamy scentralizowany framework z takimi rzeczami jak klasy bazowe i pomocniki oraz httphandlers / httpmodules. Podstawowa struktura jest dość duża i jest używana przez wszystkie aplikacje. Dzieląc w ten sposób wiele rozwiązań, zmniejszasz liczbę projektów wymaganych przez rozwiązanie, ponieważ większość z nich nie ma ze sobą nic wspólnego.
Posiadanie tak wielu projektów w rozwiązaniu to po prostu zły projekt. Nie powinno być powodu, aby mieć tyle projektów w ramach rozwiązania. Innym problemem, który widzę, są referencje do projektów, które w końcu mogą cię naprawdę schrzanić, zwłaszcza jeśli kiedykolwiek zechcesz podzielić swoje rozwiązanie na mniejsze.
Radzę to zrobić i opracować scentralizowaną strukturę (jeśli wolisz, własną implementację biblioteki korporacyjnej). Możesz udostępnić go GAC lub bezpośrednio odwołać się do lokalizacji pliku, aby mieć centralny magazyn. Tej samej taktyki można użyć również dla scentralizowanych obiektów biznesowych.
Jeśli chcesz bezpośrednio odwołać się do biblioteki DLL, będziesz chciał odwołać się do niej w swoim projekcie za pomocą copy local false (gdzieś na przykład c: \ mycompany \ bin \ mycompany.dll). W środowisku wykonawczym musisz dodać pewne ustawienia do pliku app.config lub web.config, aby odwoływał się do pliku, którego nie ma w GAC lub bin środowiska wykonawczego. W rzeczywistości nie ma znaczenia, czy jest to kopia lokalna, czy nie, lub czy dll trafi do bin, czy nawet w GAC, ponieważ konfiguracja zastąpi oba z nich. Myślę, że kopiowanie lokalnego i niechlujny system jest złą praktyką. Najprawdopodobniej będziesz musiał tymczasowo skopiować plik lokalny, jeśli chcesz debugować w jednym z tych zestawów.
Możesz przeczytać mój artykuł o tym, jak używać biblioteki DLL na całym świecie bez GAC. Naprawdę nie podoba mi się GAC głównie dlatego, że zapobiega wdrażaniu xcopy i nie powoduje automatycznego ponownego uruchomienia aplikacji.
http://nbaked.wordpress.com/2010/03/28/gac-alternative/
źródło
Ustawienie CopyLocal = false skróci czas kompilacji, ale może powodować różne problemy w czasie wdrażania.
Istnieje wiele scenariuszy, w których musisz ustawić opcję Copy Local na True, np. Projekty najwyższego poziomu, zależności drugiego poziomu, biblioteki DLL wywoływane przez odbicie.
Moje doświadczenie z ustawieniem CopyLocal = false nie powiodło się. Zobacz podsumowanie zalet i wad w moim poście na blogu „Nie zmieniaj odniesień do projektu„ Kopiuj lokalnie ”na fałszywe, chyba że rozumiesz podciągi”.
źródło