NuGet Dependency Hell
У меня есть небольшой вопрос относительно собственного сервера NuGet и собственных пакетов NuGet, которые мы продвигаем к нему. У нас есть несколько проектов и адаптированный процесс сборки TFS, который автоматически отправляет пакеты NuGet на наш сервер NuGet - пока что он работает очень хорошо.
В настоящее время мы задаемся вопросом, является ли это хорошим решением: наш основной проект использует внедрение зависимостей для разрешения зависимостей. Поэтому у нас есть структура проекта, такая как:
- Интерфейсы (.dll)
- DataLayer (.dll)
- Локализация (.dll)
- Инфраструктура (.dll)
- Приложение (.exe)
По моему мнению, я хотел бы разделить вещи на более мелкие решения, чтобы сделать вещи простыми и удобными в использовании:
- Интерфейсы (только один проект: определения интерфейсов)
- Компоненты (три проекта: с DataLayer, Локализация и Инфраструктура)
- Приложение (только один проект: только exe)
Это привело нас к проблеме, заключающейся в том, что, если кто-то меняет интерфейсы, нам придется обновлять версию пакетов nuget интерфейсов в каждом проекте компонентов, вносить изменения в нашу систему сборки, а затем обновлять само приложение. Это немного похоже на DLL Hell - кроме того, отладка и разработка немного сложнее, если вы попробуете это из-за нескольких проектов, которые разделены.
Это структура фигня? Что, по вашему мнению, является хорошим вариантом для решения зависимостей, а также для уменьшения и развертывания больших решений в более мелкие? Или вы бы порекомендовали объединить все проекты в одно большое решение?
1 ответ
Подход, который вы рекомендуете "если кто-то меняет интерфейсы, нам нужно будет обновить версию пакетов nuget интерфейсов в каждом проекте компонентов, зафиксировать изменения в нашей системе сборки", на самом деле это не лучшая практика, и вы будете сталкиваться с проблемами, поскольку вы масштаб.
В идеале вы хотите отделить разработку пакетов от разработки потребителя. Рассмотрим ваш компонентный пакет и прикладной уровень. Если у вас есть текущая настройка, когда проект приложения использует 1.0.0.0 вашего пакета компонентов. Кто-то входит и добавляет новый компонент в пакет Components и создает версию 1.1.0.0. Теперь, если вы зайдете и обновите пакет Components в проекте приложения, произойдет следующее
- Любые исправления ошибок, включенные в новые пакеты компонентов, вносятся (что может быть хорошо)
- Любые новые компоненты, добавленные в пакет, будут доступны для проекта приложения (это хорошо, только если приложение будет использовать новый компонент, иначе это не повлияет на приложение вообще)
- Любые новые ошибки, добавленные в процессе создания нового компонента, которые могли бы непреднамеренно повлиять на функциональность существующих компонентов, также будут устранены.
На мой взгляд, пункт № 3 - самое опасное влияние обновления пакета. Всякий раз, когда я узнаю, что более новая версия пакета исправит ошибку или представит новую функциональность, которая мне нужна в приложении, я согласен с риском добавления новых ошибок. Однако, если я не собираюсь использовать новые компоненты, я бы в основном внес нестабильность в проект приложения без каких-либо дополнительных преимуществ.
Процесс я бы порекомендовал-
- Отделяйте разработку каждой упаковки от ее потребителя. Этот подход довольно хорошо масштабируется и дает потребителю возможность подключиться к новым изменениям.
- Создайте систему / соглашение, где разработчики пакета могут сообщить потребителю, когда выйдет новая версия. Правильные заметки о выпуске / простой блог также может быть достаточно.
- Попросите разработчиков Приложения / проектов, использующих новый пакет, загрузить последнюю версию, только если она содержит функциональные возможности, необходимые потребителю.