Решения Visual Studio: у этих решений слишком много проектов? - PullRequest
12 голосов
/ 07 июля 2011

В компании, в которой я сейчас работаю, мы поддерживаем 4 приложения Windows, которые в некоторой степени связаны.Для каждого приложения у нас есть решение от 50 до 100 проектов.Вероятно, есть 40 или 50 проектов, которые совместно используются одним или несколькими решениями.

Просто чтобы дать вам представление, более крупное решение имеет почти 90 проектов, 20 из которых являются проектами пользовательского интерфейса (основное приложение, проекты с пользовательскими элементами управления)., UI helper projects), еще 20 проектов Business Layer, вероятно, 30 или 40 проектов уровня Data Access, а остальные проекты Windows Service и специализированные проекты

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

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

  • Большое время компиляции.
  • Классы, которые обычно должны быть частными, должны быть общедоступными, чтобы быть доступными для других проектов в том же слое.
  • Я недавно начал использовать профилировщик Eqateq.Пробная версия позволяет профилировать до 10 библиотек.Моя ситуация явно усложняет использование этого приложения.
  • Отслеживание ссылок между проектами довольно сложно.Я уверен, что между проектами много неиспользованных ссылок.

В отличие от этого, я не нашел преимущества в этой ситуации.

Итак, мои вопросы:

  • Когда вы решите создать новый проект, а не просто создать папку в текущем проекте?
  • Есть ли какие-то преимущества, которые я пропускаю?

ОБНОВЛЕНИЕ:

Имейте в виду, что я не предлагаю иметь один единственный проект для всего.Как минимум, должен быть один проект для DAL, один для BL и один для каждого приложения пользовательского интерфейса.И я понимаю, что даже это нереально для большинства приложений.Я пытаюсь понять, каковы наилучшие методы определения уровня «единой ответственности» за сборку?Я имею в виду, что это очень субъективный вопрос, который, если довести его до крайности, приведет к тому, что в каждом классе будет одна сборка.

ОБНОВЛЕНИЕ 2:

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

Ответы [ 5 ]

9 голосов
/ 07 июля 2011

Мы говорим в основном о проектах .NET, верно? Разделение вашего приложения на разные проекты / сборки вынуждает вас избегать циклических зависимостей между этими проектами, поскольку компиляторы C # и VB.NET это запрещают. Если вы поместите все в один большой проект, каждый класс может ссылаться на любой другой класс в этом проекте, что позволит вам создать настоящий кошмар зависимости. Если вы собираетесь использовать модульные тесты и разработку в команде, проще всего, если члены команды могут работать с разными изолированными библиотеками DLL и тестировать их отдельно.

Часть вашего вопроса «отслеживание ссылок»: если вы помещаете все в одну большую DLL, у вас есть те же ссылки между вашими классами, как если бы у вас были отдельные DLL, но вы больше не можете ими управлять. То же самое относится и к «частным» классам (я думаю, вы имеете в виду «внутренние»)

Что я не могу вам сказать, конечно, это то, что ваши 90 проектов - это правильно выбранные единицы работы. Это вопрос «единоличной ответственности», правильного уровня абстракции и возникающих зависимостей, который должен ответить только тот, кто подробно знает вашу прикладную систему.

РЕДАКТИРОВАТЬ: до сих пор я читал некоторые статьи (, как эта ) о сокращении времени компиляции путем определения границ компонентов по пространствам имен и помещения нескольких компонентов в одну физическую сборку / один проект VS. Чтобы сделать этот подход осуществимым, нужен, вероятно, такой инструмент, как NDepend или нечто подобное, чтобы убедиться, что между компонентами нет циклических зависимостей. Для больших проектов это, возможно, лучшая альтернатива.

1 голос
/ 12 июня 2014

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

Мое личное мнение - начинать с одного проекта на слой (как вы упоминаете)как один для GUI, один для бизнес-уровня, один для DAL и т. д. Дополнительные проекты для вашего решения должны создаваться только тогда, когда возникает конкретная потребность, а не преждевременно.На этом этапе вы можете провести рефакторинг своего решения, чтобы переместить проект «Папка» в отдельный проект.

Это обеспечит следующее: - время сборки быстрее - у вас есть точное количество проектов, которое требуется вашему проекту - выесть документированные рассуждения о том, почему вы создали конкретный проект (что нужно, чтобы он выполнялся)

Создание множества конкретных проектов в решении - это просто «Излишнее проектирование».Вы не будете чрезмерно проектировать свой код и создавать классы в местах, которые не были необходимы.Вы бы рефакторинг вашего кода, чтобы включить класс с единственной ответственностью, когда это требуется.То же самое относится к решениям и проектам.

1 голос
/ 07 июля 2011

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

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

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

1 голос
/ 07 июля 2011

Наличие многих проектов не обязательно плохо.

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

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

Этого не произойдет, если все проекты будут объединены в один проект. Конечно, вы можете заметить это, если вы запустите программное обеспечение DSM в своем коде, но imo, если ваш компилятор поможет вам, безопаснее.

То, что ваши классы могут стать частными, становится общедоступным, заставляет меня больше думать о вашем API . Не должны ли эти проекты быть объединены или не должны эти классы быть извлеченным в 3-й проект. Я стараюсь думать о слоях, думая об этих проблемах, серебряной пули нет, ты.

Для классов, которые принадлежат ONLY к проекту, я обычно добавляю "внутреннее" (или "подробное") слово к пространству имен этих "внутренних" классов, которые должны быть объявлены общедоступными. Например: вы будете знать, что никакие классы из MyApplication.Model.Publisher не должны обращаться к любым классам из: MyApplication.Model.Vendors.Internal . Эту технику я видел в Eclipse API.

Я знаю, что в C # есть ключевое слово internal , но иногда люди просто объявляют его публичным, не задумываясь об этом. Использование этого имени - более сильный подход, поскольку для того, чтобы сделать этот класс общедоступным .

, требуется больше усилий.

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

0 голосов
/ 01 июня 2019

Я думаю, что реальная проблема здесь - это единственная ответственность.Я не имею в виду дизайн класса, я имею в виду цель проекта .Net.

Обычно проект используется для:
1. Построения некоторого кода для вывода DLL, EXE, веб-сайта, API и т. Д.
2. Для контроля доступа и структурирования кода в решении

Исходя из моего опыта, большинство проектов используются для 2. В крупных решениях это приводит к тому, что структура очень широкого масштаба быстро становится неинтуитивной, замедляет сборку, замедляет визуальную студию (здравствуйте!!), Что означает огромное количествозависимости перемещаются из bin в bin, что делает все те DLL, которые вам на самом деле не нужны.

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

Как Java справляется с этим?У больших Java-проектов много циклических зависимостей?

Мой ответ на этот вопрос - иметь как можно меньше проектов.

...