ASP.NET MVC3 - 3-уровневый дизайн. Вопросы управления транзакциями и проектирования бизнес-уровня - PullRequest
6 голосов
/ 14 октября 2011

Я проектирую приложение ASP.NET MVC3, и я хотел бы иметь четкое разделение проблем в трехуровневой архитектуре. Я использую Fluent NHibernate в качестве ORM, шаблон репозитория для работы с объектами, отображаемыми NHibernate. Я хотел бы добавить надлежащий бизнес-уровень с шаблоном Unit Of Work, сохраняя часть MVC только для представления (используя ViewModels, которые отображаются на сущности nHibernate через бизнес-уровень). В этой статье прекрасно описаны комбинированные 3-уровневые архитектуры и архитектуры MVC.

Согласно этой статье MVC + единица работы + хранилище я не вижу четкого различия между бизнес-уровнями. Класс единицы работы представляет строго типизированные геттеры для каждого типа репозитория, которые выглядят подходящими для бизнес-уровня. Однако он предоставляет метод Save, который, я думаю, будет преобразован в методы BeginTransaction и CommitTransaction с помощью nHibernate. Это вызывает некоторые вопросы:

1) Является ли предоставление контроля над транзакциями MVC хорошей идеей? На каком этапе должен осуществляться контроль транзакций? Сдается мне, что MVC не должен нести ответственность за транзакции, но как этого избежать?

2) Должен ли быть какой-то автоматический способ обработки транзакций? Эта реализация ActionFilter является полуавтоматической, но управление транзакциями явно находится в разделе MVC, который не является бизнес-уровнем.

3) Является ли класс UnitOfWork таким же, как класс бизнес-уровня?
- если так, значит ли это, что мы можем добавить в него собственные методы бизнес-логики?
- если нет, переносим ли мы единицу работы в какой-либо другой класс (классы), содержащий методы бизнес-логики?

Я ценю любые идеи или примеры. Спасибо.

Ответы [ 3 ]

12 голосов
/ 16 октября 2011

Прежде всего, я хочу прояснить небольшое неправильное представление о бизнес-уровне, так как вы хотите использовать шаблон Repository, и ваша установка является кандидатом на Domain Driven Design , затем бизнес-уровень на самом деле [Модель предметной области ( Сущности и объекты-значения , где вы разрабатываете свою бизнес-логику объектно-ориентированным способом для сущностей и объектов) и прикладной уровень для координации транзакций, операций и команд на уровне домена] Таким образом, предлагаемая архитектура будет выглядеть примерно так:

  • Презентация (MVC) [OrderView, OrderPresentationModel, OrderController]
  • Приложение [OrderService]
    • Использование UnitOfWork (Транзакции) и Репозитории для выполнения логики домена
    • DTOs [OrderDTO, CustomerDTO]
  • Домен
    • Сущности и объекты-значения [Заказ, Клиент, LineItem, Адрес]
    • Интерфейсы репозитория [IOrderRepository, ICustomerRepository]
    • (необязательно) Интерфейс единицы работы [IUnitOfWork]
  • Infrastructure.DataAccess (с использованием ORM или технологии доступа к данным)
    • Репозитории [OrderRepository, CustomerRepository]
    • (необязательно) Единица работы [UnitOfWork]
  • Infrastructure.Common
    • Регистрация
    • Утилиты

Пример сценария:

[Презентация] OrderController:

 _orderService.CreateOrder(OrderDTO);

[Приложение] Служба заказа:

 _unitOfWork.BeginTransaction();
 var customer = _customerRepository.GetById(orderDTO.CustomerId);
 var order = new Order() { Customer=customer, Price=orderDTO.Price, ... }
 _orderRepository.Add(order);
 _unitOfWork.Commit();

О ваших вопросах:

1) Является ли предоставление контроля над транзакциями MVC хорошей идеей? На каком этапе должен осуществляться контроль транзакций? Сдается мне, что MVC не должен отвечать за транзакции, но как этого избежать?

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

2) Должен ли быть какой-то автоматический способ обработки транзакций? Эта реализация ActionFilter является полуавтоматической, но управление транзакциями явно находится в разделе MVC, который не является бизнес-уровнем.

Использовать транзакции на уровне приложений.

3) Класс UnitOfWork совпадает с классом бизнес-уровня? - если так, значит ли это, что мы можем добавить в него собственные методы бизнес-логики? - если нет, переносим ли мы единицу работы в какой-либо другой класс (классы), содержащий методы бизнес-логики?

Нет, это просто способ группировки задач в транзакции. Бизнес-логика фактически инкапсулирована в объектах, и если логика не связана с одним объектом, она должна быть реализована в доменных службах [TransferService.Transfer (account1, account2, amount)], для координации, доступа к репозиториям и транзакций приложения слой это место.

1 голос
/ 14 октября 2011

Вы изучили архитектуру S # arp ?Он имеет встроенную обработку транзакций MVC, используя фильтры действий.

Я, как правило, многоуровневый пурист, поэтому мне не хотелось позволять MVC открывать представление, но мне это понравилось.

Есть «за» и «против», но здесьВот некоторые преимущества шаблона Open Session In View. :

  1. Ленивая загрузка - это упростит ваш доступ к данным, если вы можете положиться на отложенную загрузку в своих представлениях MVC.Нет необходимости явно присоединяться ко всем таблицам, требуемым представлением.(Обязательно избегайте проблемы N + 1 , явно присоединяясь, когда ленивая загрузка вызовет смешное количество запросов. Сетки данных являются распространенным виновником здесь.)
  2. Упрощенный уровень BSO -вашей BSO не нужно беспокоиться о сессиях.Предполагается, что вы уже работаете в контексте сеанса.

Если вы не хотите использовать S # arp, вы все равно можете реализовать Open-Session-In-View самостоятельно с помощьютолько несколько строк кода в ActionFilter.В методе «Выполнение действия» откройте сеанс.В действии выполняется метод, фиксируй, закрывай и утилизируй.Это то, что мы делаем в моем проекте, и он хорошо сработал для нас.

0 голосов
/ 15 октября 2011

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

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

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

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

...