2010-03-23 2 views
3

Этот вопрос связан с моей разработкой ASP.NET MVC 2, но он может применяться к любой среде MVC и к вопросу о том, куда должна идти логика.MVC архитектурный вопрос - Куда должна проходить обработка платежей?

Итак, у меня есть контроллер, который принимает онлайн-платеж, такой как приложение корзины покупок. И у меня есть метод, который принимает информацию о кредитной карте клиентов:

public class CartController : Controller 
    CartRepository cartRepository = new CartRepository() 

    [HttpPost] 
    public ActionResult Payment(PaymentViewModel rec) 
    { 
     if(!ModelState.IsValid) 
     { 
      return View(rec); 
     } 

     // process payment here 

     return RedirectToAction("Receipt"); 
    } 

На комментарии process payment here должны быть обработаны обработки платежа:

  1. В контроллере?
  2. У репозитория?
  3. Где-то еще?

ответ

6

Вы хотите 3. Где-то еще.

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

Посмотрите видеоролики MVC Storefront по адресу http://www.asp.net/learn/mvc-videos/. Возможно видео # 23 (часть 22). Прошло некоторое время, так как я их рассматривал.

+0

@ 37Stars. Эти видеоролики хороши. Спасибо, что указал на меня. – Keltex

1

Я бы рекомендовал построить эту логику в бизнес-объекте и назвать это с вашего контроллера.

Например создать класс PaymentBO (статический или иначе), так что вы могли бы назвать PaymentBO.ProcessPayment (...)

1

Model должен справиться с этим, так как это компонент, который поручено работать непосредственно с (и поддержание согласованности) ваших данных. В частности:

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

+0

Модель просто объект, передаваемый в представлении. Я не думаю, что логика логики должна сидеть на модели. Тем не менее, я видел это сто раз раньше ... – hunter

+1

@Hunter Бизнес-логика не должна быть в вашей * модели просмотра *, но она должна идти в вашей модели домена, если она у вас есть. – Ryan

+0

Я бы не согласился, если учесть, что большинство моделей - это не что иное, как объект домена anyways (ASP.NET MVC размывает два, и это расстраивает). Я пытаюсь сохранить объекты домена (например, объекты, представляющие таблицы данных), и объекты модели (может быть объектом Domain или коллекцией объектов домена или что-то еще) настолько чистым, насколько это возможно, и использовать BO для этого типа вещей ... – hunter

1

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

1

Это архитектурный вопрос. Вы должны решить, для всей системы, какой подход к реализации бизнес-логики является правильным для вашего конкретного сценария. Подходы лучше всего описаны (на мой взгляд) в Martin Fowlers PoEAA.Существуют три основных модели:

  • транзакций скрипт - средства, имеющие отдельный объект для обработки конкретной транзакции
  • активная запись - средства, имеющие простую логику, размещенные непосредственно на O/RM-сопоставляются таблицы, представляющий объекты
  • модель домена - означает наличие богатого кода только модель, которая отвечает за решение проблемы

Выбор зависит от уровня сложности вашей системы. Образцы, которые я описал, упорядочены по их потенциалу для решения сложных задач (DDD лучше всего подходит для действительно сложных вещей, но сам по себе вводит некоторую «случайную» сложность).

1

Поскольку ссылки на шаблон репозитория уже имеются, вы можете подробно остановиться на Domain Driven Design (как упоминалось в Szymon).

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

На Платежного контроллер:

var paymentDetails = mapFromViewModel(rec) 
PaymentService.Pay(paymentDetails) 

На Оплата услуг

void Pay (PaymentDetails paymentDetails) 
{ 
    // leverage on rich model behavior here 
    if (User.IsHaveEnoughMoney) 
    { 
    Cashier.Pay(...) 
    } 

    // more ... 

}