ASP.NET MVC: Where do you build a view model for a view?

From inside to outside, these are our MVC application tiers:

  • MS SQL / Tables / Views / Stored Procs
  • Entity Framework 4.1 (ORM) with POCO Generation
  • Repository
  • Service (extraction) and management functions (Save)
  • Routing β†’ Controller β†’ Shaver View
  • (client) jQuery Ajax with Knockout.js (MVVM)

Everything is fine until I need to create a single ViewModel for step 5 to provide both a Razor view and a JSON / Knockout ViewModel:

  • A heading that includes all of the drop-down options and options for the fields below
  • Elements - an array of what we send to the client, which becomes a ViewModel

Since the controller will not have access to the repository directly, does this mean that I create a service for each view that allows editing content? I need to get POCO from the repository plus all the parameters for each type of field as needed.

It seems redundant to create separate services for each view. For example, a viewModel for editing an address and a separate viewModel for editing a property that also has an address. We can have a dozen forms that edit the same POCO address.

To facilitate the answer to this question, does the controller allow direct access to the repositories by leaky abstraction?

+7
source share
2 answers

Well, will your controllers get code that translates POCOs from the Entity Framework into separate view model objects?

If so, then you should move this code to a separate class and follow the principle of single responsibility. Regardless of whether this class is in the "service layer" or not, it is up to you. And whether you use AutoMapper or not is up to you. But these types of data mappers should not be part of the controller logic; controllers should be as deep as possible.


OK, now let it ignore the problem of data matching and pretend that you can always use your POCO directly as view models. Then you still need a service level, because it will broadcast between

userService.GetByUserName("bob") 

in your dumb controller and implement this in a certain way by returning

 userRepository.Users.Single(u => u.UserName == "bob") 


Combining them, your UserController ends up accepting IUserService and IUserDataMapper , and the code is super-dumb if required:
 public ActionResult ShowUserPage(string userName) { var user = userService.GetByUserName(userName); var viewModel = userDataMapper.MakeViewModel(user); return View(viewModel); } 

Now you can test the controller using stubs for both dependencies or cut out IUserDataMapper while you mock IUserService , or vice versa. Your controller has very little logic, and has only one axis of change . The same can be said for the user-mapper class and the user service class.


This morning I read an article about how you can highlight these architectural issues a bit. This is somewhat condescending, titled " Fundamentals of Software Development, Part 2: Layered Architecture ." You probably won’t be able to switch from a database application model to a permanent uninformed model, which is discussed in the article. But that may point you in the right direction.

+1
source

i personally always insert the repository / repositories into the controller. I'm not sure why you want to have a service level between the repository and the controller. if anything, you will use the specifications.

after you have done this, check automapper . its mapper, which, after proper configuration, can match your domain model with your view model and vice versa.

0
source

All Articles