Найти в Дзене
IT's BIM | Revit и C#

Как я навел порядок в плагинах для Revit, часть 1: разделение на части.

Раньше у меня все плагины жили в одном проекте. Удобно? Поначалу да. Но когда плагинов становится больше, начинается хаос: меняешь код в одном — случайно ломаешь другой, ведение гита вообще превращается в "кашу", и к тому же нельзя выключить недоделанный плагин, чтобы быстро запустить то, что уже давно работает.
Я решил это изменить. Моя цель — чтобы каждый плагин был независимым. Что это даст? А
Оглавление

Введение

Раньше у меня все плагины жили в одном проекте. Удобно? Поначалу да. Но когда плагинов становится больше, начинается хаос: меняешь код в одном — случайно ломаешь другой, ведение гита вообще превращается в "кашу", и к тому же нельзя выключить недоделанный плагин, чтобы быстро запустить то, что уже давно работает.

Я решил это изменить. Моя цель — чтобы каждый плагин был независимым. Что это даст? А вот что:

  1. Независимые Git-репозитории. Удобно смотреть по Git flow, как писался/дорабатывался/менялся плагин со временем, откатывать и коммитить изменения.
  2. Независимое версионирование. Благодаря предыдущему преимуществу можно подключить инструмент вроде GitVersion и вести версионирование плагина (1.0.0, 1.1.0 и т.д.). Теперь каждый плагин будет иметь свою личную версию.
  3. Модульность. Каждый плагин становится самостоятельным проектом, которому для работы не нужны другие плагины, а только он сам и то, на что он ссылается (NuGet-пакеты и/или проект Common/Shared)

Теория. Как выглядит решение (Solution)

Давайте посмотрим на структуру стандартного решения в C#. В Solution (решении) находится наш проект (Project):

Структура стандартного решения
Структура стандартного решения

Мой подход предполагает именно такой вид плагинов. То есть, 1 плагин — 1 решение, в котором не будет ничего лишнего.

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

Плагины, не зависящие друг от друга
Плагины, не зависящие друг от друга

Возможно, вы спросите: разве это не усложнит работу? Ведь нужно собрать всё в одну панель, да и теперь нужно один и тот же код дублировать в каждом плагине... Спокойно, мы не будем повторяться!

Для того, чтобы все это увязать вместе, мы создадим еще одно решение-агрегатор. оно будет:

  1. Иметь ссылки на все наши плагины
  2. Собирать нашу панель с кнопками

Ведь нам ничего не мешает в этот Solution добавить несколько проектов.

Solution с несколькими проектами
Solution с несколькими проектами

И мы сделаем вот такую увязку проектов между собой.

Итоговая связка проектов между собой
Итоговая связка проектов между собой

Что происходит на этой схеме?

  1. MainApp — главный проект-агрегатор. Он имеет ссылки на PylonReinforcement и EditionsController, поэтому при сборке проекта MainApp будут собираться и эти плагины тоже. А также он имеет ссылку на проект Common.csproj, который является проектом-помощником, в который мы и будем выносить всякие общие классы, сервисы и методы.
  2. EditionsController имеет ссылку на Common.csproj, так как ему понадобился какой-то функционал, который мы вынесли в Common.
  3. PylonReinforcement является самостоятельным проектом и не нуждается в каких-либо ссылках.

Логику создания панели и кнопок непосредственно пишем в MainApp. Это теперь ваша точка входа.

Что дальше?

Мы разобрались, как разделить код и навести порядок. Но осталась еще одна головная боль — версии Revit.

В следующей части покажу, как настроить мультиверсионность через Directory.Build.props. Разберем способ, который позволяет собирать плагин под версии, которых даже нет на вашем компьютере.

--

А как вы организовали свое решение? Удобно ли работать в вашем формате? Остались вопросы? Пишите обо всем в комментариях!