Где лучшее место для сопоставления из модели просмотра в модель домена?

Где лучше всего делать сопоставления из модели вида в модель домена? По сопоставлениям я имею в виду от моего объекта EditGrantApplicationViewModel до GrantApplication.

Предположим, что у меня есть следующий метод действий (частичный код):

[HttpPost]
public ActionResult Create(EditGrantApplicationViewModel editGrantApplicationViewModel)
{
   if (!ModelState.IsValid)
   {
      return View("Create", editGrantApplicationViewModel);
   }

   return View("Index");
}

Мне нужно передать EditGrantApplicationViewModel методу уровня сервиса и выполнить сопоставления в методе?

Ответы

Ответ 1

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

Почему вы можете спросить? Достаточно просто, поместив логику сопоставления в свой уровень обслуживания, он должен знать о ViewModels, о котором должен знать тот уровень сервиса, о котором НИКОГДА НИКОГДА НИКОГДА НЕ ОКАЗЫВАЕТ, - также это уменьшает гибкость приложения, в которое вы помещаете логику отображения там, поскольку вы не можете повторно используйте сервисный уровень без большого количества хаков.

Вместо этого вы должны сделать что-то вроде:

// Web layer (Controller)
public ActionResult Add(AddPersonViewModel viewModel)
{
    service.AddPerson(viewModel.FirstName, viewModel.LastName)
    // some other stuff...
}

// Service layer
public void AddPerson(string firstName, string lastName)
{
    var person = new Person { FirstName = firstName, LastName = lastName };
    // some other stuff...
}

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

UPDATE:

Чтобы отобразить объекты, возвращенные с уровня сервиса, в ViewModels, вы можете взглянуть на Automapper или Инжектор значений.

Ответ 2

Используйте AutoMapper или аналогичную структуру непосредственно в вашем контроллере.

Вот введение

Ответ 3

сделайте это на своем уровне WebUI, но не делайте этого контроллера, а вместо этого вызовите свой собственный интерфейс/класс mapper/builder

образец: http://prodinner.codeplex.com

Ответ 4

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

Например: Скажем, вы решили добавить SelectList в свою модель представления по причине предоставления прав.

public class EditGrantApplicationViewModel
{
   //...
   public SelectList ReasonForEdit {get;set;}
   //...
}

Это может быть совершенно допустимым требованием, но спросите себя, имеет ли смысл выбор SelectList на уровне сервиса? Список выбора больше относится к домену пользовательского интерфейса и на самом деле ничего не значит для уровня обслуживания. Сервисный уровень заботится только о причине не списка выбора.

Я бы взял вашу модель взгляда, переварил необходимую информацию и передал ее на ваш сервисный уровень.

[HttpPost]
public ActionResult Create(EditGrantApplicationViewModel editGrantApplicationViewModel)
{
   if (!ModelState.IsValid)
   {
      return View("Create", editGrantApplicationViewModel);
   }

   GrantApplication grantApplication = new GrantApplication();
   grantApplication. // other fields.
   grantApplication.Reason = editGrantApplicationViewModel.ReasonForEdit.SelectedValue;
   grantApplication. // other fields.
   _someService.EditApplication(grantApplication);

   return View("Index");
}

Если вы еще не просмотрели AutoMapper, так как это может помочь в использовании между моделью представления, dto и другими классами.