Некоторые рекомендации Asp.NET MVC2 для управления жирными контроллерами на уровне бизнес-сервисов - PullRequest
6 голосов
/ 10 августа 2010

Мои контроллеры становятся большими и из-под контроля.

Типичный контроллер выполняет следующие действия:

  • Определяет, имеет ли данный пользователь доступ к данному ресурсу.
  • Проверяет модель представления.
  • Преобразует ViewModel в DTOModel для сохранения.
  • Вызывает репозитории для обновления / создания новых объектов и связанных с ними других новых объектов.
  • Доступ к данным в нескольких классах помощников хранилища.
  • Проверяет, уведомлены ли пользователи.
  • Вызывает помощников для отправки писем
  • Записывает данные в базу данных через другие объекты репозитория
  • и т.д ...

Короче говоря, они оркеструют много вещей. Я бы хотел перенести все на уровень служб, но на самом деле я не видел реализованных шаблонов в примерах кода, которые мне нравятся. Я смотрел на некоторые проекты с открытым исходным кодом, такие как KiGG, Oxite, codecampserver и т. Д., Но ни один из них не решает проблему сокращения моих контроллеров. Я хотел бы избежать передачи большого количества HTTPContext, но, возможно, это невозможно.

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

Спасибо за ссылки и предложения

Ответы [ 5 ]

3 голосов
/ 11 августа 2010

Вы должны проверить этот великий сеанс MVCConf о Положите свои контроллеры на диету .

3 голосов
/ 10 августа 2010

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

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

Мой уровень обслуживания объединяет один класс обслуживания на одну бизнес-единицу.Поэтому, если в моем приложении есть проекты, а в каждом проекте есть человек, у меня был бы класс ProjectService и класс PersonService.

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

1) Получите информацию о текущем пользователе и вызовите метод авторизации соответствующего класса обслуживания.Поэтому, если пользователь пытается изменить детали проекта, я бы передал идентификатор пользователя и идентификатор проекта методу AuthorizeUser в ProjectService.Это означает, что если я изменяю способ авторизации пользователей для проектов, мне нужно только изменить метод авторизации, а не каждый контроллер.

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

3) Регистрация всех действий происходит на уровне сервиса.Это может быть автоматическим в зависимости от представляемого действия (попытка сохранить объект в БД) или ваш контроллер может явно вызвать сервисный уровень для регистрации действия.

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

Редактировать : Это делает контроллеры маленькими, так как они действительно содержат только несколько обращений к сервисному слою и все (Авторизация, выполнение действия, Показать представление). Конец редактирования

Наконец, на сайте asp.net есть учебное пособие для выполнения проверки на уровне сервиса.Этот урок можно найти здесь .

1 голос
/ 10 августа 2010

Мне кажется, что вы полагаетесь на то, что ваш контроллер играет слишком много ролей.

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

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

0 голосов
/ 10 августа 2010

Ну, кое-что из этого зависит от того, что вы подразумеваете под «контроллером». Если вы используете аннотации данных для проверки и фильтры действий для ведения журнала, это прекрасно. Там нет никакой логики в контроллере там. Вы используете ViewModels и строго типизированные представления? Кажется, что модель, с которой работает ваш контроллер, уже должна быть упрощенной DTO, в отличие от полной сущности и создания DTO для отправки обратно. Мне трудно представить себе ситуацию, когда контроллер отправит электронное письмо или проверит его отправку. Это должно быть передано на сервисный уровень. Я бы также внимательно посмотрел на контроллер, который работает на «связанных объектах». Вероятно, он должен вызывать единственный метод в хранилище, который обрабатывает это.

Я не открыл Nerd Dinner, так что я не могу поклясться, что там, но это может стоить изучить?

0 голосов
/ 10 августа 2010

Здесь, в моей компании, у нас всего 5 проектов:

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

В этом случаевсе проекты имеют ссылку на ORM, затем представление имеет ссылку на контроллер, контроллер на бизнес-логику и бизнес-логику на доступ к данным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...