Совместное использование классов или интерфейсов между различными проектами

17

Я искал некоторые ответы в SO или здесь, но безрезультатно, поэтому я бы спросил вас.

Предположим, у меня есть два разных проекта - например, серверная часть и клиентская часть приложения. Я разрабатываю свою собственную часть, в то время как мой друг делает вторую. Но мы оба должны использовать некоторые общие интерфейсы, такие как Userили AccountInfoили ChangableAccount... что угодно, чтобы обеспечить совместимость. Например, если клиенты отправляют данные пользователя на сервер, сервер должен работать в том же классе. То же самое с интерфейсами и т. Д. Кроме того, если есть какие-либо изменения в общем интерфейсе, оба проекта должны адаптировать свой код к новой ситуации.

Единственное решение, которое я вижу сейчас, - это создать один дополнительный проект, в котором определены все общие вещи. Мы, я и мой друг, должны добавить этот проект в качестве зависимости от основного проекта (клиента или сервера). Общим проектом может управлять какая-то система контроля версий, поэтому у нас всегда самое современное состояние.

Какое другое решение вы бы предложили? Как такие проблемы решаются в профессиональных приложениях?

guitar_freak
источник
1
Вы должны контролировать версию, делитесь ли вы чем-то или нет. Вы говорите, что не используете контроль версий для клиентских и серверных проектов? Если так, исправьте это немедленно.
Себастьян Редл

Ответы:

15

создать один дополнительный проект, в котором определены все общие вещи

Это как раз первый шаг для обмена повторно используемыми деталями - и это самая простая часть. Более сложная часть состоит в том, чтобы решить, будут ли два проекта, использующие общую библиотеку, иметь независимые циклы выпуска (или нет), и если будет возможно, чтобы «проект А» использовал версию 1.0 вашей общей библиотеки, в то время как проект В использует версия 2.0 одновременно .

Если вы хотите, чтобы последнее было возможно, вам нужна строгая схема управления версиями и управление выпусками для вашей библиотеки (и номера версий как часть имени файла библиотеки, как предложено @RoryHunter). Вы также должны позаботиться о обратной совместимости в вашей библиотеке в этой ситуации. Ваша библиотека должна управляться как отдельный продукт, добавляя в нее модульные тесты, чтобы убедиться, что разные версии в рабочей среде будут хорошей идеей, и такой инструмент, как Maven, тоже может иметь смысл.

Если, однако, вы хотите предотвратить эту ситуацию, вы должны управлять «проектом A», «проектом B» и вашей библиотекой как общим проектом с объединенным процессом разработки, сборки и выпуска. Это позволит гораздо чаще и чаще менять общий интерфейс разделяемой библиотеки, чем в первом сценарии. И вам не понадобится что-то вроде Maven или номера версий в имени файла библиотеки. Но компромисс в том, что A и B больше не могут развиваться независимо.

Док Браун
источник
13

Ваше решение является правильным. Поместите общий код в другой проект, который создает свой собственный файл JAR, и используйте его в обоих проектах. При сборке JAR-файла вы можете включить версию в имя, например, в стиле Debian;

libmyproject-shared-1.0.jar

Это не предотвращает проблемы с версиями, но должно помочь. Я никогда не использовал Maven, но я понимаю, что это может помочь в этой ситуации.

Рори Хантер
источник
2

создать один дополнительный проект, в котором определены все общие вещи

Именно так .Net ожидает, что вы это сделаете.

Абстрагируйте эти объекты в третью сборку и сделайте ссылку на это из обоих проектов. Я бы предложил сделать это как Интерфейсы, что чище, но ...

Остерегайтесь сериализации:

  • Единственный способ, которым я мог напрямую сериализовать / десериализовать объекты между двумя программами (правда, это было какое- то время назад с использованием Framework 2.0), это установить «общую» сборку в глобальный кэш сборок на клиентских и серверных компьютерах. Если сборка была «локальной» для каждого проекта, то Framework воспринимал их как отдельные типы и отказывался сериализовать одну в другую.
  • И [де] сериализация объектов, типизированных как интерфейсы, является чем-то вроде «вызова». Оригинальный неинтерфейсный тип, похоже, не «делал это» через «канал» сериализации, поэтому получатель не знал, какой конкретный тип «построить» из входящего потока.
Фил В.
источник
1

Как и предполагали другие, ваш мыслительный процесс точен. В профессиональном плане большинство из них используют что-то вроде Maven или Gradle для эффективного управления этими зависимостями.

BrandonV
источник