W naszej pracy mamy kilka różnych aplikacji .net, które mają wiele podstawowych funkcji. Zbudowaliśmy te aplikacje przy użyciu czystej architektury n-tier, ale osiągnęliśmy ten moment, kiedy zdajemy sobie sprawę, że kilkakrotnie zaimplementowaliśmy te same funkcje. Oczywiście narusza to OSUSZANIE i chcielibyśmy to poprawić. Już teraz używamy Nuget do osiągania sukcesów w zakresie powszechnego kodu kleju (podłączanie IoC, rejestrowanie, ustawienia), ale chcielibyśmy również udostępniać nasze dane i warstwy biznesowe między wszystkimi naszymi aplikacjami. Chodzi o to, że interfejs użytkownika będzie obsługiwał tylko te części warstwy biznesowej, których faktycznie potrzebuje.
Z początku wydaje się to prostym problemem, ale ciągły rozwój może spowodować pewne pułapki i nie jesteśmy pewni, jak postępować. Powiedzmy, że tworzymy naszą Jedną warstwę biznesową, aby rządzić nimi wszystkimi. Dla zwięzłości nazywam to „Fundacją”. Przenosimy nasze aplikacje do korzystania z Fundacji i wszystko działa świetnie. Fundacja jest dystrybuowana do lekkich warstw interfejsu użytkownika za pośrednictwem nugetu, a my dobrze wyglądamy. Ale potem zaczynamy dodawać funkcje do naszych aplikacji i wpadamy w kłopoty.
Powiedzmy, że pracujemy nad Projektem A i dodajemy nową funkcję, która wymaga zmian w Foundation. Wprowadzamy zmiany w fundamencie (Foundation-A) i wypychamy je do kanału nuget jako niestabilny pakiet. Projekt A otrzymuje najnowszy pakiet nugetów i wszystko jest w porządku. Tymczasem inny programista pracuje nad Projektem B. Pobiera najnowszą Fundację z kontroli źródła, ale pobiera ją ze stabilnej gałęzi, aby nie zawierała zmian w Projekcie A. Dokonuje zmian i stworzył Foundation-B. I wszystko jest dobrze. Ale potem odkrywamy, że funkcjonalność implementacji Foundation-A i Foundation-B, która faktycznie może współdzielić kod, łączymy je. Tymczasem Foundation-C unosi się tam z własnymi zmianami. W końcu Foundation-B jest gotowa do produkcji, więc ją wypychamy. Ale potem musimy zaktualizować produkcję A, B,
Wydaje się, że to może działać, ale martwimy się pracą z różnymi schematami baz danych i utrzymywaniem synchronizacji między różnymi gałęziami repozytorium Foundation, a także repozytoriami Project A, B i C. Wygląda na to, że prawdopodobnie zajmie to dużo pracy ręcznej, co otwiera możliwość błędów. Chciałbym, aby było to jak najbardziej zautomatyzowane.
Oto stos, którego używamy: C #, TFS z Continuous Integration, Nuget. Nasze aplikacje to różnego rodzaju aplikacje ASP.NET. Jesteśmy gotowi spojrzeć na różne SCM, jeśli to ułatwi sprawę.
Szukam sposobów na utrzymanie rozsądku w Nuget dzięki różnym gałęziom kodu źródłowego. Nie chcemy przypadkowo wypchnąć kodu programistycznego do produkcji, ponieważ odwołujemy się do niewłaściwego pakietu Nuget.
Odpowiedzi:
Tutaj zaczyna się twój problem ... Nie rób tego.
Wszelkie zmiany w Foundation v1.0 z natury powinny być cenne dla wszystkich konsumentów Foundation, w przeciwnym razie nie należy ona do Foundation. Tak więc, tworząc pakiet nuget, zrób to jako oficjalną, stabilną wersję Foundation (tj. V1.1), lub w ogóle go nie rób.
Projekt B powinien budować ulepszenia Fundacji w normalny sposób, ale (w dobry sposób zarządzania źródłami) powinien łączyć się ze zmianami łącza (v1.1) przed wypchnięciem stabilnej Fundacji (v1.2) do nugetu.
Inne projekty, które mogą korzystać z ulepszeń Foundation, mogą w razie potrzeby zaktualizować odwołania do modeli użytkowych lub w razie potrzeby trzymać się starszych wersji.
Zgadzam się z @Giedrius ; wydaje mi się, że jest to bardziej kwestia kontroli źródła / rozgałęzienia w tym sensie, że jeśli rozgałęzienie / połączenie Fundacji jest obsługiwane poprawnie, problemy z zarządzaniem pakietami stają się dyskusyjne.
źródło
Zmień swój zduplikowany kod na funkcje, które można zastosować w bardziej abstrakcyjny sposób, i umieść je we własnych bibliotekach lub ramach. Spraw, by były luźno sprzężone i agnostyczne dla architektury, a nigdy nie powinieneś mieć problemu. Jeśli potrzebujesz inspiracji, przestudiuj, w jaki sposób .NET Framework wyodrębnia pojęcia, wykorzystując takie elementy, jak interfejsy, rodzaje i wzorce oprogramowania, takie jak
Dispose()
.Pamiętaj też, że nie cały zduplikowany kod jest naprawdę powielony; niektóre z nich to kod kleju lub kod, który w przeciwnym razie jest niezbędny do utrzymania architektury, więc nie obawiaj się, że jesteś zbyt SUCHY.
źródło
Ponowne użycie kodu
Istnieje wiele podejść do ponownego użycia kodu, które zyskały przychylność na przestrzeni lat. Każde podejście ma swoje miejsce, a co ważniejsze, jego problemy , ale realne sposoby ponownego wykorzystania kodu w .NET to:
Wspólna biblioteka. Kod, który jest potrzebny w więcej niż jednym miejscu, jest umieszczany we wspólnej bibliotece, a wszystkie inne części bazy kodu mają wówczas pojedyncze odniesienie do tego kodu. Zasadniczą wadą jest to, że kończy się większość projektu w zależności od biblioteki, która zawiera wiele niezwiązanych funkcji. To zły pomysł z punktu widzenia zapewnienia jakości.
Wspólny kod źródłowy. Kod potrzebny w więcej niż jednym miejscu jest zapisywany raz i umieszczany w pliku źródłowym we wspólnej strukturze katalogów. Wszystkie projekty, które potrzebują tego kodu, dołączają ten plik jako jeden ze swoich plików źródłowych. Zapewnia to ponowne użycie kodu, a zalety jednokrotnego zapisu wymagają wielu. Jednak. Jego wadą jest to, że możliwe staje się kompilowanie różnych części projektu z różnymi wersjami tego kodu - co może powodować pewne subtelne wady, które mogą być bardzo trudne do wykrycia i zidentyfikowania przez zapewnienie jakości.
Usługa. Wspólny kod jest implementowany jako usługa, do której mają dostęp inne aspekty. Ma to tę zaletę, że we wdrożeniu będzie pojedyncza usługa i pozwala uniknąć zależności. Wprowadzi jednak opóźnienia i awarie. Takie podejście działa dobrze w dużych rozproszonych produktach, w których wysoka dostępność i odporność na uszkodzenia są już zrozumiane i zarządzane.
Zarządzanie NuGET
Tutaj masz o wiele bardziej interesujący problem. Zarządzanie wieloma konfiguracjami. Radzę tutaj, aby nie zarządzać zróżnicowaną bazą klientów z różnymi wersjami kodu, ale z plikami konfiguracyjnymi. Do zarządzania są co najmniej 3 warstwy danych konfiguracyjnych. Podstawowa (wewnętrzna) konfiguracja produktu, której klient nigdy nie widzi. Domyślne opcje konfiguracji, które klient może zmienić, i ostatnia warstwa opcji konfiguracji, które klient zmienił. Oddzielając te różne warstwy, będziesz mógł wdrażać aktualizacje bez niszczenia konfiguracji klientów.
źródło
Myślę, że problemem nie jest nuget / kontrola źródła / rozgałęzienie, ale to, co wpada w kod klejenia.
Robert ma miłą odpowiedź, aby zobaczyć cały obraz, polecam zastanowić się, jakie zależności te wspólne narzędzia wprowadzą do każdego projektu:
http://ayende.com/blog/3986/let-us-burn-all-those-pesky-util-common-libraries http://blog.jordanterrell.com/post/CommonUtility-Libraries-Dead.aspx
Najlepszym sposobem na uniknięcie piekła jest otwarcie kodu źródłowego. W ten sposób zaczniesz się martwić, że żadna logika biznesowa nie zostanie upubliczniona, więc żadne konkretne zależności projektowe nie zmienią się w kod kleju, że byłby wystarczająco abstrakcyjny, aby mógł być ponownie użyty przez kogokolwiek, nawet poza twoją firmą - i jeśli to klejenie kod będzie wystarczająco dobry - dostaniesz również wkład społeczności.
źródło
Rozwiązanie jest proste: stwórz dla niego osobny projekt i zarządzaj nim jako osobną rzecz: własne wymagania, testy, konwencje, dokumentacja, planowanie, ludzie itp. W ten sposób zapewniasz wysoką jakość i możliwe przełomowe zmiany oceniane najpierw, zanim stworzą problem.
Lub jeszcze lepiej: uczyń go „otwartym oprogramowaniem” w swojej organizacji. Tak więc każdy może zmienić kod, ale tylko kilka wybranych osób będzie miało pełne prawa do zatwierdzania. Ci ludzie będą odpowiedzialni za zapewnienie jakości i poprawności funkcji.
źródło