Хорошая практика в решениях Visual Studio [закрыто]

10

Надеюсь, относительный простой вопрос. Я начинаю работу над новым внутренним проектом по созданию управляемости ремонтируемых устройств внутри зданий.

База данных хранится удаленно на веб-сервере и будет доступна через веб-API (вывод JSON) и защищена с помощью OAuth. Внешний интерфейс GUI выполняется в WPF, а бизнес-код в C #.

Исходя из этого, я вижу разные уровни презентации / приложения / хранилища данных. Будет код для управления всеми аутентифицированными вызовами API, классом для представления сущностей (бизнес-объектами), классами для создания сущностей (бизнес-объектами), частями для графического интерфейса WPF, частями моделей представления WPF и так далее.

Лучше всего создать это в одном проекте или разбить их на отдельные проекты?

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

JonWillis
источник
1
Я бы разделил их на то, что имеет смысл для проекта.
Ramhound
Есть ли у кого-нибудь еще какие-либо мысли, один на проект для удержания интерфейсов, как предложил MattDavey. Я использовал этот подход раньше, чтобы избежать упомянутых зависимостей. Или интерфейсы для класса x должны находиться в том же проекте, что и класс x.
ДжонВиллис
Кроме того, какие слои вы все используете. Я видел несколько разных вариантов, хотя основными из них являются презентация / приложение / инфраструктура. Некоторые также разбивают приложение на 2 части: приложение + сервис. В некоторых моделях также упоминается определенный слой для бизнес-логики, который, по моему мнению, может быть включен в сами бизнес-объекты.
ДжонВиллис

Ответы:

8

Это зависит от размера проекта

Вот рекомендации, которые я склонен использовать

  • Небольшой проект с несколькими страницами или меньше, я почти всегда придерживаюсь одного проекта.

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

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

  • Если приложение имеет несколько целей, каждая из которых имеет свои собственные представления, модели представления и т. Д., То я обычно разделяю каждую часть на свою область. Если каждый раздел небольшой, я разделяю их папкой. Если каждый раздел большой, я разделю их по проекту.

  • Если у меня есть несколько проектов , которые должны ссылаться на один и тот же набор объектов ( ViewModelBase, RelayCommand, и т.д.), я создам проект только для общих объектов инфраструктуры.

  • Если у меня есть большое количество общих пользовательских стилей / шаблонов / ресурсов, я создам проект только для них.

Как примечание, я допустил ошибку в своем первом большом проекте WPF и разделил их, поместив Модели в один проект, Представления в другой и ViewModels в третий. Теперь я могу сказать вам, что это не тот путь, так как обслуживание становится кошмаром :)

Рейчел
источник
Любопытно, какие проблемы с обслуживанием у вас возникли при разделении слоев?
Ян
@ Рейчел, я буду использовать WPF. Поэтому было бы интересно узнать, как вы организовали проект в конце. Я думаю, что я могу помнить, что маленький проект MVC был болью при разделении 3 частей на 3 dll. Для WPF My view будет GUI, сущность / бизнес-объект, который будет изменен, и ViewModel взаимодействие между ними. ViewModel будет иметь дело с логикой вызова хранилища для загрузки / сохранения исправлений (которые, в свою очередь, имеют фабрики / веб-API и т. Д.).
ДжонВиллис
1
@Ian Самая большая проблема заключалась в том, что большинство незначительных изменений, таких как добавление одного поля, требовало от меня поиска моделей, представлений, ViewModel и DAL в 4 отдельных библиотеках. Проект, над которым я работал в то время, был довольно велик, и я потратил больше времени, чем хотел бы найти конкретные файлы. С тех пор я изменил , чтобы держать связанные объекты вместе, так что , например , что - нибудь , связанных с поиском , таких как SearchView, SearchViewModelи SearchResultModelвсе были бы сгруппированы вместе в папке , и я нашел , что это делает приложение легче поддерживать.
Рэйчел
@ Я также помню, что у меня были проблемы с зависимостями и циклические ссылки, потому что, несмотря на все мои усилия, некоторые слои должны были ссылаться на другие, но этот слой ссылался на них, поэтому у меня были некоторые уродливые обходные пути до рефакторинга
Rachel
1
@JonWillis Большинство моих проектов WPF разбиты на основе пунктов, указанных в моем ответе. Обычно DAL является собственным слоем, и каждый Модуль или Раздел проекта группируется (либо в своей собственной папке, пространстве имен, либо в проекте в зависимости от размера проекта). Так, например, все объекты поиска будут вместе, в том числе Interfaceдля уровня данных, но фактический уровень доступа к данным для поиска будет в библиотеке DAL. Довольно часто у меня есть Infrastructureили Commonбиблиотека, которая содержит общие базовые классы, интерфейсы и вспомогательные классы.
Рэйчел
14

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

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

Брайан Бетчер
источник
9

ИМХО по отдельности почти всегда лучше. Я почти всегда отделяю свой слой данных, если проект не является тривиальным. Причина в том, что слой данных имеет тенденцию проходить чаще всего. Редко вы подключите графический интерфейс к нескольким слоям данных и ожидаете, что он будет работать хорошо. Гораздо более распространенный сценарий состоит в том, что у вас есть один слой данных, и вы хотите, чтобы он был распределен по нескольким графическим интерфейсам (например, ASP.Net, WPF и приложение Silverlight). Это здорово, когда вы можете просто создать проект уровня данных и вставить эту DLL в качестве ссылки в следующем построенном вами графическом интерфейсе.

Морган Херлокер
источник
+1 Когда я начинаю новые проекты, я довольно часто создаю имитируемый слой данных, который хранит данные в памяти. Позволяет мне сначала приступить к созданию остальной части приложения. Затем я могу поменять его на «настоящий» слой доступа к данным позже.
MattDavey
Будете ли вы рассматривать сущности (DTO), факторы и классы, используемые для связи с веб-сервером, как часть уровня данных?
ДжонВиллис
@JonWillis - Нет, наверное, не все из них. Я бы поместил фабрики и классы для веб-сервера в пространство имен проекта библиотеки классов. Мой типичный слой данных не содержит ничего, кроме необходимых файлов dbml и / или файлов edmx. Однако, как правило, я даю материалу библиотеки / фреймворка свой собственный проект. Их определенно не нужно вкладывать в проект с графическим интерфейсом, хотя я вижу, что люди делают это постоянно.
Морган Херлокер
Реально, однако, сколько времени вам понадобится, чтобы взять несколько пространств имен и добавить их в новый проект. Я чувствую, что это довольно легкая работа по рефакторингу.
Дидье А.
4

Для меня 4 * это магическое число. Один проект для каждого уровня и один проект, который определяет все интерфейсы / DTO, необходимые для связи между ними.

* 7, если вы считаете модульные тесты

MattDavey
источник
2

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

Джереми
источник
2

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

Том Сквайрс
источник
На какие слои вы отделяете? Есть ли у вас отдельные уровни Application / Services, и если да, то как они на самом деле отличаются. Содержится ли ваша бизнес-логика в приложении / услуге, или это методы для реальных бизнес-объектов?
ДжонВиллис
1

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

Это работает, когда я делаю своего рода инверсию зависимостей, чтобы поместить все «контракты», интерфейсы, абстрактные классы, объекты передачи данных в одну сборку. В другой сборке я положил все, что говорит с базой данных. Модульные тесты получают свою сборку. Если пользовательский интерфейс принципиально непроверяем (например, Win.Forms ASP.NET), то есть существенное преимущество разделения пользовательского интерфейса на тестируемый код и непроверяемый код - каждую сборку. Иногда начинает появляться какой-то код, который не имеет ничего общего с базой данных, пользовательским интерфейсом или чем-то, о чем я упоминал до сих пор - это код, который мне хотелось бы видеть в .NET Framework. Этот код я добавлю в сборку утилит, или, по крайней мере, в любую корневую сборку (вероятно, с интерфейсами).

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

Некоторые выпуски Visual Studio сталкиваются с проблемами производительности примерно на 15 сборках, иногда это зависит от типа проекта. Однако иногда может помочь стратегическая выгрузка файлов проекта.

MatthewMartin
источник
Я единственный разработчик в компании, на данный момент. А также только что из университета, поэтому стараюсь привить передовой опыт в более крупные проекты как можно скорее. Я заинтересован в том, чтобы сделать его обслуживаемым, потому что спецификация системы сильно изменилась еще до того, как я начал ее документировать, вопреки просьбам системы как можно скорее. На ваш взгляд, будет ли подходящим решением иметь сборку, которая содержит только интерфейсы? Таким образом, зависимость должна быть только от интерфейсов и фабричных классов.
ДжонВиллис
1
Да. Лучше понять мотивацию разделения сборки, но если вы (или члены вашей команды) этого не делаете, это все равно недорогой маневр. Таким образом, даже если в конечном итоге все сборки зависят от всех сборок и нет надежды на модульное тестирование, перемещение объектов, которые ведут себя как контракты (интерфейсы, абстрактные классы), в свою собственную сборку, является шагом в правильном направлении и имеет несколько недостатков.
МэтьюМартен
-2

Единственная веская причина иметь более одного проекта - это если вам нужно совместно использовать набор классов и файлов в нескольких приложениях.

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

Прочитайте эту статью, чтобы лучше понять, почему это так: http://lostechies.com/chadmyers/2008/07/16/project-anti-pattern-many-projects-in-a-visual-studio- решение-файл /

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

Дидье А.
источник
Встречные аргументы на downvote приветствуются.
Дидье А.