Udostępnianie klas lub interfejsów między różnymi projektami

17

Szukałem odpowiedzi w SO lub tutaj, ale bez rezultatów, dlatego o to zapytam.

Załóżmy, że mam dwa różne projekty - na przykład część serwera i część klienta aplikacji. Rozwijam swoją część, podczas gdy mój przyjaciel tworzy drugą. Ale oboje powinniśmy korzystać z niektórych popularnych interfejsów, takich jak Userlub AccountInfolub ChangableAccount... w celu zapewnienia zgodności. Na przykład, jeśli klienci wysyłają dane użytkownika do serwera, serwer powinien działać na tej samej klasie. To samo dotyczy interfejsów itp. Ponadto, jeśli wystąpią jakiekolwiek zmiany we wspólnym interfejsie, oba projekty powinny dostosować swój kod do nowej sytuacji.

Jedyne rozwiązanie, jakie widzę teraz, to stworzenie jednego dodatkowego projektu, w którym zdefiniowane są wszystkie typowe rzeczy. My, ja i mój przyjaciel, powinniśmy dodać ten projekt jako zależność do głównego projektu (klienta lub serwera). Projektem współdzielonym może zarządzać jakiś system kontroli wersji, więc zawsze mamy najbardziej aktualny stan.

Jakie inne rozwiązanie zaproponowałbyś? Jak takie problemy są rozwiązywane w profesjonalnych aplikacjach?

Guitar_freak
źródło
1
Powinieneś kontrolować wersję, czy coś udostępniasz, czy nie. Czy mówisz, że nie używasz kontroli wersji dla projektów klienta i serwera? Jeśli tak, napraw to natychmiast.
Sebastian Redl,

Odpowiedzi:

15

stworzyć jeden dodatkowy projekt, w którym zdefiniowane są wszystkie wspólne rzeczy

Jest to dokładnie pierwszy krok do udostępnienia części wielokrotnego użytku - i to jest łatwa część. Trudniejszą częścią jest decyzja, czy dwa projekty korzystające ze wspólnej biblioteki będą miały niezależne cykle wydania (czy nie) i czy powinno być możliwe, że „projekt A” korzysta z wersji 1.0 udostępnionej biblioteki, podczas gdy projekt B używa wersja 2.0 jednocześnie .

Jeśli chcesz, aby ta ostatnia była możliwa, musisz mieć ścisły schemat kontroli wersji i zarządzania wydaniami dla swojej biblioteki (i numery wersji jako część nazwy pliku biblioteki, jak sugeruje @RoryHunter). W takiej sytuacji powinieneś również zadbać o kompatybilność wsteczną w swojej bibliotece. Biblioteką należy zarządzać jako oddzielny produkt, dodając do niej testy jednostkowe, aby upewnić się, że różne produkcyjne wersje będą dobrym pomysłem, a narzędzie takie jak Maven może mieć sens.

Jeśli jednak chcesz zapobiec tej sytuacji, powinieneś zarządzać „projektem A”, „projektem B” i biblioteką jako wspólnym projektem, z połączonym procesem rozwoju, kompilacji i wydania. Umożliwi to zmianę wspólnego interfejsu biblioteki współdzielonej znacznie częściej i częściej niż w pierwszym scenariuszu. I nie będziesz potrzebował czegoś takiego jak Maven lub numery wersji w nazwie pliku biblioteki. Ale kompromis polega na tym, że A i B nie mogą być już opracowywane niezależnie.

Doktor Brown
źródło
13

Twoje rozwiązanie jest właściwe. Umieść wspólny kod w innym projekcie, który tworzy własny plik JAR, i użyj go w obu projektach. Podczas budowania pliku JAR możesz chcieć dołączyć wersję do nazwy, np. W stylu Debiana;

libmyproject-shared-1.0.jar

Nie zapobiega problemom z wersją, ale powinno pomóc. Nigdy nie korzystałem z Maven, ale rozumiem, że może to pomóc w tej sytuacji.

Rory Hunter
źródło
2

stworzyć jeden dodatkowy projekt, w którym zdefiniowane są wszystkie wspólne rzeczy

Właśnie w ten sposób .Net oczekuje, że to zrobisz.

Wyodrębnij te obiekty w trzecie Zgromadzenie i odwołaj się do nich z obu projektów. Proponuję zrobić to jako interfejsy, które są czystsze, ale ...

Uważaj na serializację:

  • Jedynym sposobem mogę bezpośrednio serialise / deserialise obiektów pomiędzy dwoma programami (wprawdzie to było podczas temu użyciu Framework 2.0) było zainstalować „wspólny” zespół do Global Assembly Cache na obu komputerach klienta i serwera. Jeśli zestaw był „lokalny” dla każdego projektu, wówczas Framework postrzegał je jako odrębne typy i odmawiał [de] serializacji jednego z nich na drugi.
  • A [de] szeregowanie obiektów Typowanych jako interfejsy to trochę „wyzwanie”. Oryginalny, nieinterfejsowy typ zdawał się nie „przechodzić” przez „potok” serializacji, więc odbiornik nie wiedział, jaki konkretny typ „zbudować” z przychodzącego strumienia.
Phill W.
źródło
1

Jak sugerują inni, twój proces myślowy jest dokładny. Profesjonalnie większość osób użyłaby czegoś takiego jak Maven lub Gradle, aby efektywnie zarządzać tymi zależnościami.

BrandonV
źródło