Как передать сложную ViewModel на сервисный уровень в ASP.NET MVC?

Скажем, у меня есть RegisterModel для регистрации пользователей и некоторый UserService, реализующий IUserService.

public interface IUserService
{
   User CreateUser(User newUser);
}


[HttpPost]
public ActionResult Register(RegisterModel model)
{
            if (ModelState.IsValid)
            {

                // ... logic for newuser

                User user = _userService.CreateUser(newuser);

               _authenticationService.SetAuthenticatedUser(user);

                return RedirectToRoute("Homepage");
            }

            return View(model);
        }

Учитывая, что RegisterModel может быть очень сложным, где должна быть логика для сопоставления RegisterModel с объектом User?


person Eldar    schedule 19.02.2011    source источник


Ответы (1)


Вы никогда не передаете модель представления службе. Служба даже не знает о существовании модели представления, которую вы могли определить на своем уровне графического интерфейса пользователя (ASP.NET MVC). Сервис работает с моделями предметной области. Лично я использую AutoMapper для сопоставления между моделями представления и моделями и наоборот, поэтому эта логика переходит на уровень сопоставления.

person Darin Dimitrov    schedule 19.02.2011
comment
Итак, что здесь делает сервисный уровень? Если контроллер обрабатывает получение классов моделей из репозитория и обновляет их с помощью AutoMapper, что здесь делает сервисный уровень? - person LukLed; 19.02.2011
comment
@LukLed, сервисный уровень предоставляет бизнес-операции, которые вы можете выполнять с помощью модели. Эти бизнес-операции могут быть повторно использованы во многих различных приложениях: ASP.NET MVC, WinForms, WPF, представленных как службы WCF, ... Модели представлений - это просто временные объекты, отвечающие конкретным потребностям данного представления. Они просто представляют реальную модель. Модели представления — это не то, чем должен заниматься сервисный уровень. Они слишком специфичны для данного приложения. - person Darin Dimitrov; 19.02.2011
comment
@Дарин Димитров: Мой вопрос, что он здесь делает? Можете ли вы привести пример связи между контроллером и сервисом в этой конкретной ситуации, когда мы создаем пользователя? - person LukLed; 19.02.2011
comment
@LukLed, вот пример: действие контроллера получает модель представления из представления, оно использует уровень сопоставления (в моем случае AutoMapper) для сопоставления этой модели представления с моделью, а затем вызывает метод службы, передавая ему эту модель. Поэтому здесь важно отметить, что контроллер взаимодействует с представлением только через модели представления: он получает модели представления в представление и передает модели представления в представление. Вот как я это делаю. - person Darin Dimitrov; 19.02.2011
comment
@Дарин Димитров: Если у службы есть метод с именем CreateUser, какие параметры он должен принимать? Он не может взять модель, собранную из представления, так что же для этого нужно? Другая модель? - person LukLed; 19.02.2011
comment
@LukLed, нужна модель: public void CreateUser(User user). Конечно, если у вас нет представления, содержащего достаточно информации, чтобы удовлетворить ваш сервисный уровень, вам может потребоваться переосмыслить свои представления/сервисные уровни. Поэтому, если у вас уже есть сервисный слой, принимающий User, вы должны организовать себя таким образом, чтобы представление содержало всю необходимую информацию для создания пользователя, иначе сервисный слой, который у вас есть, не может быть повторно использован. - person Darin Dimitrov; 19.02.2011
comment
@Darin Dimitrov Если у меня есть данные для двух сущностей EF, пользователя и профиля, стоит ли создавать общую модель RegisterModel (не модель представления) в домене или расширять CreateUser (пользователь, профиль профиля)? - person Eldar; 19.02.2011
comment
@eldar, я думаю, что оба подхода хороши. И, кстати, для меня модели EF не должны рассматриваться как модели (если только вы не используете подход Code First) => они просто автоматически генерируются транспортными объектами базы данных помощника, которые должны отправляться в репозиторий CRUD, а не в службу, потому что они часто загрязнены/ связанных с конкретной технологией доступа к данным, которую вы используете (в данном случае EF). - person Darin Dimitrov; 19.02.2011
comment
@Darin Dimitrov Мне лень писать логику сущностей от руки =) Не могли бы вы порекомендовать шаблон T4 или, может быть, другой подход? Спасибо! - person Eldar; 20.02.2011
comment
@eldar, я никогда не использовал T4, поэтому прошу прощения, но не могу вам ничего порекомендовать в этом направлении. Я всегда предпочитаю писать логику домена вручную. - person Darin Dimitrov; 20.02.2011