0

I have an ASP.NET MVC3 in C# and Razor. The architecture of the application is divided in Data Access Layer (EF classes + Repository), Service Layer, Controller, ViewModels and View.

My ViewModel exposes a method Fill which accepts as parameter the data collection to display in the View. In order not to have coupling between the components, the Fill method has to be called from the Service Layer or from the Controller?

CiccioMiami
  • 8,028
  • 32
  • 90
  • 151

2 Answers2

2

Definition: Model (as in MVC) = Service layer (in this case)

The controller should be conspired as a glue between the view and the model. The view should not be aware of the model and vice versa.

The answer to your question is therefore that the Controller should contain all logic used to move information from the model to the view model. It's perfectly fine to use any class from the Model within the view model.

Update in answer to comments

Like I said. I have no idea how your classes looks like or what you have to do to generate the navigation.

  1. The controller should be used to assemble the information required by the view model
  2. The controller should not have any business logic

This means that you might have to create new classes in your service layer to be able to achieve those two goals.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • thanks for your answer. As I wrote in the reply to the answer above if I use navigation properties within the ViewModel I create coupling between ViewModel and EF. I want to know where to extract this value not to create coupling – CiccioMiami Feb 17 '12 at 12:35
  • an interface named `INavigationService` in the service layer which is used to populate the view model. – jgauffin Feb 17 '12 at 12:45
  • according to your answer therefore it should be the service layer filling the viewmodel and not the controller? – CiccioMiami Feb 17 '12 at 13:00
  • 1
    No. the controller can use the `INavigationService` to fetch the information and then put it in the view model. It's hard to give a proper answer when we don't know how your view model looks like or how the information that it should be populated with looks like. The question is very domain specific. But the general answer is that it's always the Controller that should assemble the information required. – jgauffin Feb 17 '12 at 13:03
  • ok perfect, let's go forward. Suppose a method implementing INavigationService, queries the repository and has a Product object and a string object. Which object type would it pass to the Controller? – CiccioMiami Feb 17 '12 at 13:12
  • Any object which could be used to generate the navigation without introducing business logic in the controller. – jgauffin Feb 17 '12 at 13:13
  • so I have to create one object for each combination of navigation? Suppose instead of having just one foreign key I have 8 of them. I have to create a method for each combination of the 8 FKs? – CiccioMiami Feb 17 '12 at 13:23
  • Ok perfect now it is clear. Let's clarify one last point. I create a new class filled by the service layer, ProductInfo, that contains same fields as Product where CategoryId is replaced by CategoryName. The method called from the controller (assume ServiceLayer is static) has signature ProductInfo ServiceLayer.GetProduct(//parameters). Correct? – CiccioMiami Feb 17 '12 at 13:38
1

It would be better to remove the Fill function from your ViewModel then the ViewModel wont depended on your data layer.

I would then use something like Automapper in the controller to map the DataObject To the ViewModel before returning the view.

ActionMethod:

public ActionResult Edit(int id)
{
    var data = DataRepo.Get(id);
    var viewMode = Mapper.Map<ViewModel>(data);
    return View(viewModel);
}
Bjarki Heiðar
  • 3,117
  • 6
  • 27
  • 40
  • thanks. My situation is a bit different. Suppose I have an object with navigation properties and i want to get a vale of another table by using the navigation property. How would you approach the problem? – CiccioMiami Feb 17 '12 at 12:12
  • Are you mapping from 2 tables to one ViewModel? – Bjarki Heiðar Feb 17 '12 at 12:14
  • To be short, in my class Product I have several fields and a field CategoryId foreign key to table Category. In my ViewModel I have all the fields of Product plus CategoryName. That means in order to get the CategoryName I have to use the navigation property from Product to Category. If I use it in the ViewModel I create coupling between the latter and the EF – CiccioMiami Feb 17 '12 at 12:33
  • I would add a view in the database for this. then you only need one IO to get the data you need for the viewModel. – Bjarki Heiðar Feb 17 '12 at 12:37
  • The problem is this database view which type of object gives me back? – CiccioMiami Feb 17 '12 at 13:01
  • If you are using EF you will get a new Objecttype back. then you use that object to show your Product with all the category names. and if you need to save the Product object back to db then map the dbViewObject to product object and save it. – Bjarki Heiðar Feb 17 '12 at 13:03