7

Say I have RegisterModel for user registration and some UserService that implementing 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);
        }

Given that RegisterModel might be very complex, where is the logic should go for mapping RegisterModel to User object

Eldar
  • 862
  • 9
  • 22

1 Answers1

16

You never pass a view model to a service. A service doesn't even know about the existence of a view model that you might have defined in your GUI (ASP.NET MVC) tier. A service works with domain models. Personally I use AutoMapper to map between view models and models and vice versa, so this logic goes into the mapping layer.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • So what does service layer do here? If controller handles retrieving model classes from repository and updating them using AutoMapper, what does service layer do here? – LukLed Feb 19 '11 at 20:36
  • 1
    @LukLed, the service layer exposes business operations that you could do with the model. Those business operations could be reused among many different applications: ASP.NET MVC, WinForms, WPF, exposed as WCF services, ... View models are just temporary objects to answer a specific needs of a given view. They are just a representation of the real model. View models are not something that a service layer should bother with. They are too specific to the given application. – Darin Dimitrov Feb 19 '11 at 20:38
  • @Darin Dimitrov: My question is, what does it do here? Can you give an example of communication between controller and service in this specific situation, when we are creating user? – LukLed Feb 19 '11 at 20:41
  • 1
    @LukLed, here's an example: a controller action receives a view model from a view, it uses a mapping layer (AutoMapper in my case) to map this view model to a model and then invokes a service method passing it this model. So the important thing to note here is that the controller communicates with the view only through view models: it receives view models to the view and it passes view models to the view. That's how I do it. – Darin Dimitrov Feb 19 '11 at 20:42
  • @Darin Dimitrov: If service has a method called `CreateUser`, what parameters should it take? It can't take model collected from view, so what does it take? Another model? – LukLed Feb 19 '11 at 20:45
  • @LukLed, it takes a model: `public void CreateUser(User user)`. Of course if you don't have a view that contains enough information to satisfy your service layer you might need to rethink your views/service layers. So if you already have a service layer taking a `User` you should arrange yourself in such a way that the view contains all the necessary information for creating a user, otherwise the service layer you have cannot be reused. – Darin Dimitrov Feb 19 '11 at 20:46
  • @Darin Dimitrov If I have data for two EF entities User and Profile, is it worth to create shared RegisterModel (not viewmodel) in the Domain, or extend CreateUser(User user, Profile profile)? – Eldar Feb 19 '11 at 20:50
  • 2
    @eldar, I think both approaches good. And by the way for me EF models should not be considered as models (unless you use Code First approach) => those are just autogenerated by assistant database transport objects that should go into a CRUD repository and not a service because they are often polluted/related with the specific data access technology you are using (EF in this case). – Darin Dimitrov Feb 19 '11 at 20:51
  • @Darin Dimitrov I am lazy to handwrite Entities logic =) Could you recommend T4 template or maybe another approach? Thx! – Eldar Feb 19 '11 at 21:01
  • @eldar, I've never used any T4 so I am sorry but can't recommend you anything in this direction. I always prefer to write my domain logic manually. – Darin Dimitrov Feb 19 '11 at 21:03