Как лучше всего делиться проектом Visual Studio (сборкой) между решениями? - PullRequest
11 голосов
/ 29 мая 2009

Предположим, у меня есть проект "MyFramework", в котором есть некоторый код, который используется во многих решениях. Каждое решение имеет свое собственное управление исходным кодом (SVN).

MyFramework является внутренним продуктом и не имеет официального графика выпуска, как и решения.

Я бы предпочел не создавать и не копировать библиотеки DLL во все 12 проектов, то есть новые разработчики должны иметь возможность просто выполнить svn-checkout и приступить к работе.

Какой лучший способ поделиться MyFramework со всеми этими решениями?

Ответы [ 7 ]

7 голосов
/ 29 мая 2009

Поскольку вы упоминаете SVN, вы можете использовать externals , чтобы "импортировать" проект фреймворка в рабочую копию каждого решения, которое его использует. Это привело бы к такой раскладке:

C:\Projects
  MyFramework
    MyFramework.csproj
    <MyFramework files>

  SolutionA
    SolutionA.sln
    ProjectA1
      <ProjectA1 files>
    MyFramework   <-- this is a svn:externals definition to "import" MyFramework
      MyFramework.csproj
      <MyFramework files>

С этим решением у вас есть исходный код MyFramework, доступный в каждом решении, которое его использует. Преимущество состоит в том, что вы можете изменить исходный код MyFramework из каждого из этих решений (без необходимости переключаться на другой проект).

НО : в то же время это также является огромным недостатком, поскольку позволяет очень легко сломать MyFramwork для некоторых решений при модификации его для другого.

По этой причине я недавно отказался от этого подхода и теперь отношусь к нашим проектам фреймворка как к совершенно отдельному решению / продукту (с их собственным графиком выпуска). Все остальные решения включают конкретную версию двоичных файлов каркасных проектов.

Это гарантирует, что изменение, внесенное в библиотеки инфраструктуры, не нарушит решение, использующее библиотеку повторно. Теперь для каждого решения я могу решить, когда я хочу обновиться до более новой версии библиотек инфраструктуры.

4 голосов
/ 29 мая 2009

Это звучит как катастрофа ... как вы справляетесь с разработчиками, разрушающими / нарушающими работу других ...

На вашем месте я бы поставил MyFrameWork в совершенно отдельное решение. Когда разработчик хочет разработать один из 12 проектов, он открывает это проектное решение в одной IDE и открывает MyFrameWork в отдельной IDE.

Если вы строго назовете свой MyFramework Assemby & GAC и будете ссылаться на него в других своих проектах, то «Копирование DLL» не будет проблемой.

Вы просто создаете MyFrameWork (а событие PostBuild может запустить GacUtil для помещения его в кэш ассемблера), а затем создаете свой другой проект.

2 голосов
/ 29 мая 2009

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

Во-первых, безопаснее, если вы используете относительные URI (начинающиеся с символа ^) для определений svn: externals и помещаете проекты в один и тот же репозиторий, если это возможно. Таким образом, определения останутся действительными, даже если сервер Subversion будет перемещен на новый URL.

Во-вторых, убедитесь, что вы следуете следующей подсказке из книги SVN. Используйте PEG-REVs в определениях svn: externals, чтобы избежать случайных поломок и нестабильных тегов:

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

2 голосов
/ 29 мая 2009

Требуется ли для работы любого из 12 решений регулярно вносить изменения в код "framework"?

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

Поскольку изменения в структуре, сделанные с помощью одного решения, затронут все другие решения, произойдут перерывы, и вам придется с ними справляться.

Как только вам редко придется менять среду, когда вы работаете в решениях (это должно быть вашей целью), я бы вместо этого включил ссылку на библиотеку DLL и обновлял библиотеку DLL в каждом решении только по мере необходимости.

2 голосов
/ 29 мая 2009

«Лучший способ» будет зависеть от вашей среды. Я работал в среде непрерывной интеграции на основе TFS, где ночная сборка развернула двоичные файлы на общем ресурсе. Все зависимые проекты относятся к доле. Когда это стало медленным, я создал несколько инструментов, позволяющих разработчикам иметь локальную копию общих двоичных файлов без изменения файлов проекта.

1 голос
/ 03 октября 2013

Масштабируемое решение - svn-external в каталоге решений , чтобы импортированные проекты отображались параллельно с другими проектами. Причины этого приведены ниже.

Использование отдельного подкаталога для "импортированных" проектов, например externals, через svn-external кажется хорошей идеей, пока у вас нет нетривиальных зависимостей между проектами. Например, предположим, что проект A зависит от проекта в проекте B, а проект B - от проекта C. Если у вас есть решение S с проектом A, вы получите следующую структуру каталогов:

# BAD SOLUTION #
S
+---S.sln
+---A
|   \---A.csproj
\---externals
    +---B     <--- A's dependency
    |   \---B.csproj
    \---externals
        \---C     <--- B's dependency
            \---C.csproj

Используя эту технику, вы можете даже получить несколько копий одного проекта в своем дереве . Это явно не то, что вы хотите.

Более того, если ваши проекты используют зависимости NuGet , они обычно загружаются в каталог packages верхнего уровня. Это означает, что NuGet ссылки проектов в подкаталоге externals будут повреждены .

Кроме того, если вы используете Git в дополнение к SVN, рекомендуемый способ отслеживания изменений состоит в том, чтобы иметь отдельный репозиторий Git для каждого проекта, а затем отдельный репозиторий Git для решения, которое использует * 1027. *git submodule для проектов в пределах. Если подмодуль Git не является непосредственным подкаталогом родительского модуля, то команда подмодуль Git создаст клон, который является непосредственным подкаталогом .

Еще одним преимуществом наличия всех проектов на одном слое является то, что вы можете затем создать «супер-решение», которое содержит проекты из всех ваших решений (отслеживаемых через Git или svn-external), что, в свою очередь, позволяет вам проверьте с помощью одного решения - перестройте, чтобы любое изменение, внесенное вами в один проект, соответствовало всем другим проектам .

# GOOD SOLUTION #
S
+---S.sln
+---A
|   \---A.csproj
+---B     <--- A's dependency
|   \---B.csproj
\---C     <--- B's dependency
    \---C.csproj
1 голос
/ 29 мая 2009

Я согласен с другим постером - это звучит как проблема. Но если вы не хотите делать это «правильным способом», я могу придумать два других способа сделать это. Мы использовали что-то похожее на номер 1 ниже. (для собственного приложения C ++)

  1. скрипт, командный файл или другой запущенный процесс, который выполняет получение и сборку зависимости. (только один раз). Он создается / выполняется только в том случае, если в репо нет изменений. Вам нужно будет знать, какой тег / ветку / версию получить. Вы можете использовать bat-файл в качестве шага предварительной сборки в ваших файлах проекта.

  2. Хранить двоичные файлы в репо (не очень хорошая идея). Даже в этом случае зависимые проекты должны получить и знать, какую версию получить.

В конечном итоге то, что мы пытались сделать для наших проектов, имитировало то, как мы используем и ссылаемся на сторонние библиотеки.

Что вы можете сделать, это создать пакет выпуска для зависимости, который устанавливает переменную пути env для себя. Я хотел бы позволить нескольким версиям этого существовать на машине, а затем зависимые проекты ссылаться / ссылаться на конкретные версии.

Что-то вроде

$(PROJ_A_ROOT) = c:\mystuff\libraryA

$(PROJ_A_VER_X) = %PROJ_A_ROOT%\VER_X

и затем укажите нужную версию в зависимых решениях либо по конкретному имени, либо с помощью версии env var.

Не красиво, но работает.

...