Может ли сервисный уровень содержать несколько сервисов?

Я реконструирую большое приложение ASP.Net с веб-формами, добавляя сервисный уровень, чтобы снять нежелательную ответственность с уровня представления.

Я видел много примеров, когда все сервисные методы содержались в одном классе.

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

Есть рекомендации, плюсы/минусы?

Ричард

P.S. Обратите внимание, что я не говорю об уровне веб-службы, WCF или чем-то еще, хотя это может стать более актуальным позже.


person Richard    schedule 11.10.2012    source источник


Ответы (3)


принципы SOLID, особенно Принцип единой ответственности предполагает, что наличие всех ваших функций в одном объекте — плохая идея, и я склонен согласиться. По мере роста вашего приложения будет сложно поддерживать один класс.

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

Чем больше функций содержит этот единственный класс, тем больше зависимостей он потребует. Вполне возможно, что у вас будет конструктор службы с длинным списком параметров просто потому, что класс покрывает много вопросов и зависит от других функций на более низком уровне, таких как ведение журнала, связь с базой данных, аутентификация и т. д. Допустим, потребитель этой службы хочет вызвать один и только один конкретный метод этого класса перед уничтожением экземпляра. Ваш контейнер IOC должен будет внедрить каждую зависимость, которая может «возможно» понадобиться службе во время выполнения, даже если потребитель будет использовать только 1 или 2 из этих зависимостей.

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

Обычно доза практичности наряду с хорошо известной моделью или принципом — лучший путь вперед.

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

person Baldy    schedule 13.10.2012
comment
Это отличный ответ, и он подтверждает то, что подсказывало мне мое внутреннее чувство. - person Richard; 14.10.2012

Конечно, может. Более того, я считаю, что было бы лучше выделить из этого класса уровня обслуживания Бога несколько интерфейсов по функциональности (т.е. ISecurityService, INotificationService и т. д.) и реализовать каждый интерфейс в отдельном проекте. Кроме того, вы можете использовать некоторый контейнер IOC для разрешения класса, реализующего интерфейс службы. Таким образом, вы можете независимо изменять реализацию каждой службы, не меняя функциональность клиента.

По крайней мере, впервые вы можете пометить свой суперкласс службы как частичный, а затем разделить его по функциональности на несколько файлов .cs(.vb) с осмысленными именами и сгруппировать их вместе в Visual Studio. Это упростит навигацию по методам обслуживания.

person Yuriy Rozhovetskiy    schedule 11.10.2012
comment
Я опасаюсь иметь отдельные проекты, так как приложение большое, как и поверхность сервисного слоя. Я понимаю, почему наличие безопасности в другом сервисном проекте было бы удобно для повторного использования. Согласен на фронте IoC, поскольку преимущества, которые он приносит, — это то, к чему я хочу пойти. А пока - надеюсь, у кого-то еще есть мнение - я разобью его на несколько классов обслуживания. - person Richard; 12.10.2012

Мой подход к структурированию приложения состоит в том, чтобы начать с разделения приложения на два проекта AppX.Web (логика пользовательского интерфейса) и AppX.Business (бизнес-логика), но при этом оставить их в одном решении VS. Уточнение структуры между бизнес-логикой и логикой пользовательского интерфейса помогает понять, какие службы совместно используются несколькими веб-страницами, а какие являются локальными для одной веб-страницы. Вам следует избегать повторного использования кода непосредственно между веб-страницами, если вы обнаружите, что это необходимо, вам, вероятно, следует переместить этот фрагмент общего кода на уровень бизнес-логики.

При реализации проекта бизнес-логики вы должны попытаться создать отдельные классы для разных типов бизнес-логики. Эти классы, конечно, могут общаться друг с другом, но веб-страницы не должны общаться друг с другом.

После того как вы отделили логику пользовательского интерфейса от бизнес-логики, вы можете продолжить разбивать код AppX.Business на более мелкие части, если это необходимо. Общие примеры включают:

  • AppX.Data: уровень доступа к данным (DAL), который изолирует все манипуляции с данными от фактической бизнес-логики.
  • AppX.Dto: объекты передачи данных (DTO), которые могут быть полезны во многих сценариях, например. при отправке данных в клиентский браузер для обработки jQuery
  • AppX.Common: Общая логика, которая является общей для многих других приложений, это могут быть вспомогательные классы, которые вы создали ранее, или вещи, которые следует просмотреть после проекта для включения в классы поддержки всей компании.

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

При реализации службы WCF вполне возможно сделать все это в одном классе. В службе WCF нет реальной бизнес-логики, поскольку она просто выполняет прямые вызовы бизнес-логики.

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

  • Начните с создания проектов AppX.Web и AppX.Business.
  • Определите службы и создайте классы в AppX.Business для этих служб.
  • Переместите код из проекта AppX.Web в новые классы в AppX.Business и убедитесь, что вы вызываете их из веб-проекта.
  • Продолжайте с дополнительной разбивкой, если вы чувствуете, что вам это нужно!
person Mattias Lindberg    schedule 13.10.2012
comment
Привет, проект полностью разделен. Мне было интересно узнать о передовой практике для сервисных слоев, так как до этого это была просто единица работы на фасаде в клиенте, и это становилось неудобным в больших приложениях. - person Richard; 14.10.2012