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.
Related
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.
We have an MVC3 project that uses nHibernate; there is a separate model project that contains all the model classes which is used by the repository and service layers. The models make use of data annotations like DisplayAttribute and RequiredAttribute from System.ComponentModel.DataAnnotations.
There are also attributes such as RemoteAttribute that are contained in System.Web.Mvc.
This of course means that the model project now has a dependency to a particular front end technology.
Assuming the solution could have other front ends what would be the best way to handle this dependency link?
RemoteAttribute does not belong in the model, since it specifies a controller/action to validate the property on the server, and the model shouldn't have knowledge of concepts like controller, action or route. The presentation layer depends on the model, not the other way around.
I would create a view model that inherits the model, overrides the property (must be virtual) and adds the RemoteAttribute. This way you can avoid duplication and mapping, although that's also an alternative.
To reduce dependency between database model and frontend technology, you can use special view model for validation qnd other front end actions in controller and put data from viewmodel to database entity after it.
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.
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.