Где лучшее место для сопоставления из модели просмотра в модель домена?
Где лучше всего делать сопоставления из модели вида в модель домена? По сопоставлениям я имею в виду от моего объекта 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 и другими классами.