MVC Business Logic Организация - PullRequest
7 голосов
/ 02 апреля 2011

Я пытаюсь выучить MVC с ASP.Net и читаю книгу Стива Сандерсона. Одна вещь, которая меня смущает, это где разместить бизнес логику?

Например, при удалении продукта у Сандерсона есть только метод в его CartController, который вызывает метод Delete в productsRepository. Это странно для меня, потому что если бы существовала какая-либо бизнес-логика, например, обеспечение того, чтобы продукт сначала не находился ни у кого в корзине, и т. Д., Он должен был бы быть либо в репозитории продуктов, либо в CartController.

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

Разве он не должен использовать класс, который содержит бизнес-логику и вместо этого вызывает метод удаления хранилища? Хранилище является переменной-членом класса бизнес-логики '?

Ответы [ 5 ]

8 голосов
/ 02 апреля 2011

Я обычно структурирую свои решения MVC таким образом, как:

  • X.Core
    • общие методы расширения, ведение журнала и другой код не-веб-инфраструктуры
  • X.Domain
    • доменные объекты и репозитории
  • X.Domain.Services
    • доменные службы для организации сложных доменных операций, таких как добавление продукта в корзину
  • X.Application.Core
    • логика приложения (инициализация (регистрация маршрута, конфигурация IoC и т. Д.), Веб-расширения, фильтры MVC, базовые классы контроллера, механизмы просмотра и т. Д.)
  • X.Application.Models
    • просмотр моделей классов
  • X.Application.Services
    • классы обслуживания, которые могут возвращать ViewModels путем доступа к репозиториям или доменным службам, а также наоборот для обновлений
  • X.Application.Web
    • контроллеры, представления и статические ресурсы

Некоторые из них можно комбинировать, но их разделение облегчает поиск объектов и обеспечивает соблюдение границ слоев.

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

public virtual ActionResult ProductCart()
{
    var applicationService = <obtain or create appropriate service instance>
    var userID = <obtain user ID or similar from session state>
    var viewModel = applicationService.GetProductCartModel( userID );
    return View( "Cart", viewModel );
}

Типичное действие контроллера для добавления товара в корзину может выглядеть примерно так:

public virtual ActionResult AddProductToCart( int productID )
{
    var domainService = <obtain or create appropriate service instance>
    var userID = <obtain user ID or similar from session state>
    var response = domainService.AddProductToCart( userID, productID );
    return Json( new { Success = response.Success, Message = response.Message } );
}
3 голосов
/ 03 апреля 2011

Я также прочитал первую версию Сандерсона его книги, и это было фантастически - очень простой способ взять и начать использовать ASP.NET MVC.К сожалению, вы не можете сразу перейти от концепций его книги к написанию большого поддерживаемого приложения.Одним из самых больших препятствий является выяснение того, куда поместить вашу бизнес-логику и другие проблемы, которые лежат между пользовательским интерфейсом и постоянным хранилищем (концепция, называемая разделением проблем или SOC).

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

Мое решение имеет отдельный уровень обслуживания.Контроллеры связываются с сервисным уровнем (используя Dependency Injection - Ninject).Сервисный уровень имеет доступ к моим доменным объектам / бизнес-логике и моим репозиториям (NHibernate - также запущен с Ninject).У меня очень мало логики в моих представлениях или контроллерах - контроллеры служат в качестве координатора, и я стараюсь поддерживать свои действия контроллера как можно более тонкими.

Мой уровень домена (сущности, бизнес-логика и т. Д.) Имеетнет зависимостей.В нем нет ссылок на мой веб-проект или на мой репозиторий.Это то, что часто называют POCO или обычными старыми объектами C # / CLR.

РЕДАКТИРОВАТЬ: я заметил в одном из ваших комментариев, что вы используете EF.EF не поддерживает POCO без использования того, что называется Code First (находился в состоянии предварительного просмотра Community Technology Preview, когда я проверял это в августе прошлого года).Просто к вашему сведению.

1 голос
/ 04 августа 2011

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

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

NDecision делает бизнес-логику дерева решений достаточно простой для реализации, и если вы поклонник синтаксиса Gherkin и методов кодирования Fluent, вы будете чувствовать себя как дома, используя ее. Снимок кода ниже взят с сайта проекта и демонстрирует, как можно реализовать бизнес-логику.

NDecision example code

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

Надеюсь, это поможет.

0 голосов
/ 03 апреля 2011

Я пытаюсь изучать MVC с ASP.Net и читаю книгу Стива Сандерсона.Одна вещь, которая меня смущает, - это где разместить бизнес-логику?

В модели (M в MVC) или на уровне домена.Это отдельный набор типов (предпочтительно в отдельном проекте), которые представляют модели доменов, сервисы и репозитории.

0 голосов
/ 02 апреля 2011

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

...