In an MVC application where should the database entities be restricted to. They should obviously be used in the data layer, but should they be used/returned in the business/service layer too? What about ViewModels? Where should their use be restricted to? Are there any other models that should have their scope restricted?
Based on my understanding, it depends on the scope of your application. You can return the entities to the business layer if you have a simple usage, say you are using all the properties of the entity class in the view.
Suppose, if you have a complex model where you want a combination of different entities that you are going to use in the view, then you use view models. In the latter case you save all the data into view model in data-access layer and return the view model to business layer or you can get the models into business layer and save them into view model at this level and return to the controller action method. But the controller action method should finally get the view model.
Related
I have a viewmodel that needs to be populated with data from an entity
I call this method within my controller
public AssessmentResponseVM ConfigureAssessmentViewModel(AssessmentResponseVM model)
{
if (model.AssessmentID != null)
{
model.Questions = getQuestionAndAnswerList(model.AssessmentID);
}else
{
model.Questions = getQuestionAndAnswerList(null);
}
return model;
}
It basically retrieves a list of questions and answers for the supplied assessment and assigns them to a property of the viewmodel. Where should this ConfigureAssessmentViewModel method live? At the moment it is sat in my controller but i'm not sure I like it there. Should it sit in the viewmodel class or elsewhere?
In this case you should just keep this logic in your controller and return an Enumerable of questions:
var questionsAndAnswersList = getQuestionAndAnswerList(model.AssessmentID);
Also note that you are checking for a null AssessmentID but then passing null into getQuestionAndAnswerList anyway.
then your View should use
#model IEnumerable<Question>
You may also want another view here that knows how to display only questions. See this other question on display/editor templates.
getQuestionsAndAnswerList most likely belongs in a Service/Business logic class that knows how to access the data and translate it into something the controller knows how to use. How you separate your ViewModel classes and Service classes really depends on the size of your application and preference.
A good answer would be quite exhaustive, but basically what you have here is what is part of an object mapping layer. I've seen lots of different architectures that handle this differently. Usually the best thing is to be consistent.
For me, because my business models and view models are two different structures, and view models are tailored highly to a view, or sometimes a handful of views in a controllers, then the controller is responsible for populating the view model from the business model. This is because my approach usually involves a data access layer, business layer, and view layer(consisting of controller, view model, view).
There is no business logic in my controllers, and so they are very thin, and all they are really responsible for is calling into the business layer, retrieving business models, and then populating view models with data from the business layer.
The controller is sort of a glue between the UI and the business layer.
Therefore, in this case if I had a function like this that did something as simple as setting some data on the ViewModel, and it for some reason needed to be reused by multiple controller actions, then I'd just make it a private function of the Controller.
If you were working with a different architecture, that might not be appropriate. I've seen cases where the business layer returned ViewModels instead of business models, and so that mapping occurred in the business model.
If you were working with an existing architecture, I would put that code as a private function in the same class that creates the view model initially, i.e. the class containing new AssessmentResponseVM(...
I have read that my models should be just dumb containers for data and that kind of appeals to me.
If this is the case then my understanding is that controllers make calls to the Repository which will just fill up the models and pass them back like so.
using (var userRepo = new UserRepository())
{
var users = userRepo.GetAll();
return View(users);
}
If I want to add a method like AlertUserOrderHasBeenRecd() where would I put it?
If I put it into the Repository then the Repository is doing more than just Data Persistence.
If I put it into the Model then the model is no longer a dumb data container.
I could also add an additional class that is passed in an order model and a user model and takes an action without knowing anything about EF.
Or something else.
Is there a generally accepted best way of handling this?
This method could be defined in a service layer. The service layer depends on the repository because it contains business operations which could be composed of multiple CRUD operations from the repositories. Then your controller will take the service layer instead of a repository and invoke the business method on it.
As an alternative to introducing yet another abstraction layer to your application you could favor query objects over repositories.
I've had very nice result separating Models and ViewModels. The ViewModels are just the dumb containers for data (DTOs). The Models are the business layer (the business of the UI). So, the result is:
Controller: handles the navigation through the site.
Models: Fills and process the ViewModels requested by the Controller.
ViewModel: DTO's with data that will be represented.
View: The visual representation of the data in the ViewModel.
In this architecture your method will be in the Model.
In our MVC implementaton,
we have a View, Controller and a Model
The Model is an .edmx file (Entity Framework).
Our controller calls a Repository where we do get the data from the Entity Framework.
Is the Repository considered part of the Model then?
Is it usually part of the Model as the M is MVC can be many layers.
The repository is not part of the Model, it is it's own separate entity that can also be invoked at the Controller and/or Model level when needed. The repository is simply an area of storage, i.e. a database.
As a breakdown:
The controller takes care of all the web requests, i.e. GET and POST. It can also populate a model and return the appropriate view for that request.
The model contains the domain objects and logic to perform (i.e. extracting information from the repository and manipulating the data to be passed to the view).
The view returns the markup which is based upon the data stored within the model.
In certain implementations additional logic such as checking conditions and Repository calls also take place at the controller level, which is a technique known as Fat Controller Thin Model.
I was reading this tutorial for MVC3 with Linq to Entities using Model First.
http://msdn.microsoft.com/en-us/data/gg685489.aspx
A quote from the article states
Our controllers will use the BlogDataEntities to retrieve data for us.
In a more advanced application, you should separate logic further and
would not be working with the BlogDataEntities directly from the
controller.
What is the general structure of this other layer between the entities and Controller in an MVC application? What is the purpose?
I usually have a bastardized ViewModel (see http://en.wikipedia.org/wiki/Model_View_ViewModel) which contains the business logic, can fetch/save from EF and is what the view is bound to. The controller doesn't do much but instantiate the viewmodel and depending on the controller action, call a method within the view model.
Some people might break that up even further and have a full blown ViewModel which has no logic in it,just data. A business layer with all of the logic and the ability to move data from EF to the ViewModel and vice-versa.
In the article "BlogDataEntities" is not the name for some specific entity classes (what the name suggests) but the name of the DbContext.
I guess it means that you would try to hide that you work with EF by not instantiating the DbContext, but by using a repository-implementation like this
http://msdn.microsoft.com/en-us/data/ff707264#_Toc261428890
At the start of the development I faced with problem called "an impedance mismatch between domain model and the view". To solve this problem I decide to use ViewModel pattern - for every view (that is strongly typed) we create viewmodel class. But where is the validation logic is locate - in viewmodel classes or in our domain model objects? And where we need to perform operations to query database - in controller action, and then populate viewmodel or straight in viewmodel?
Thank you.
You should have validation logic for the viewmodel. This is what the view sends and what should be validated. As far as populating the viewmodel is concerned here's how to proceed: write a repository which queries the database and returns models. Then map those models to viewmodels (AutoMapper can help you here). Finally return viewmodels to the view. This also works the other way around: the users POSTs some data to a controller action as the form of a viewmodel which once validated is mapped back to a model and passed to the repository for update.
As an alternative to Data Annotations you may take a look at FluentValidation for validating your view models. It integrates nicely with ASP.NET MVC.