By reading at several articles posted here, I get mismatched information about how to properly configure a project.
I am looking for advise about how the pros do it at the enterprise level.
I see different schools of though about this, some people design in a truly N-Tier fashion, others prefer to use EF Code First directly in the MVC application and have FAT models and sort of have one big MVC app with logical separation of concerns, etc.
So for a mid-size project this is my set up and I want to ask for your opinions about it.
MVC application
Models -- Here my models have just what the view needs, validation logic, etc. These models are designed to pass data between the controller and views only.
Controllers -- Call the service layer where business logic lives and gets domain models back if needed. Converts domain models into view models and vice-versa.
Service layer
This is were the business (domain) logic lives.
The service layer is also in charge of communicating with the data layer to perform CRUD operations.
The service layer returns domain models to the controller in the MVC application and also expects domain models when invoked.
Data Repository layer
The data layer is a thin wrapper around EF and performs CRUD operations.
usually I will have a Code First approach where entity models are created for me by EF.
I convert the EF code first models to domain models and return these to the service layer.
The data layer also expect domain models from the service layer that in turn I convert to EF code first models and persist to the DB.
Domain Model layer
These are the domain models that are used and shared thorough the applications layers.
What's best design?
What's expected at the enterprise level?
There's nothing particularly wrong with the approach you've laid out. However, I do see it as overly complex. Your repository layer, in particular, is a totally unnecessary level of abstraction. You could simply just roll the EF stuff into your service layer and call it a day. Having to convert the entity into a domain model and then to a view model, is frankly, a pain. Just map your entity to your view model and back.
The only thing you should really bear in mind is that ASP.NET MVC very loosely follows the MVC pattern. There's no such thing as a true MVC Model, and trying to force something like an entity class into that mold is a huge mistake. Your Model is the combination and interaction of your entity class, view models that represent that class, and the querying logic you tuck away in your service layer.
I would like you to suggest have these layers in your project ----
Entites Layer--
it should contains only all your poco classes in a model folder.Nothing else
Data Layer----
It should contain Db interactions logic.
Also your Dbcontext class should reside in this.
You may use Repository Pattern and unit of work pattern for better seperation of concern.Use dependency injection to resolve dependencies using Unity Container(there are many other container also available).Please have a look on these design pattern and container.there are many articles available on net for this.Simply go through them thoroughly.
Service Layer ----
It should contain only service methods to call into your controller as your controller should not directly talk to data Layer.Its a much better approach and prevent your business logic from being exposed to external attacks.
MVC Layer or UI layer ---
It should contain only the controllers whose work is to call services and business logics inside them.
and View folder where we have all the views to be shown to the end users.
Its a pretty big question.I hope may be u get some idea from this.
Related
with nTier architecture it is common to create a data, business, workflow and ui layer. In this setup, your data layer and business layers are separated and can be reused by other layers.
In ASP.NET MVC it seems that the model is acting as both the business and data layer as clearly the model is the data and all documentation indicates that business logic belongs in the model.
How is this architecture promoting good separation of concerns when these two layers are mixed?
There is a difference between View Models and Domain Models. Domain Models is your application domain. These models can be used everywhere, in any tier and they are usually placed in a separate shared project. Your View Models are just for the UI. They are dependent on your page needs/structure. Let's say you want to create user management page, than your view model may be a class with 2 properties User and List<Role> where User and Role are domain models.
And finally, your Data Models usually are just database transfer objects. Entity Framework models are usually used as Data and Domain models at the same time.
So, answering your question: you choose your comfortable level of mixing models by yourself. The problem is if you don't want to mix, then you will have quite a bit of model duplications across the solution and you will have to do mapping from one type of model to the other manually or with help of libraries like AutoMapper. That's why developers choose some compromise.
Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user. (Wikipedia)
We should take into account that when we talk about ASP.NET MVC, we are talking about "User Interface" so, it is a user interface framework not an application one. In MVC, concerns are separated in three components: Model, View and Controller.
In multi-layer or multi-tier architecture, concerns are mostly separated in Presentation, Application, Business and Data access layers which is an application framework architecture and ASP.NET MVC belongs to the Presentation layer.
All in all, separation of concern is completely achieved if we distinguish between Application and Presentation frameworks.
Andrei M is spot on. I agree with the difference between View models and domain models. It may help to think of the M in MVC as a model for your views, and these "view models" should not have any knowledge of where they get their data from. Therein lies the separation of concerns. A controller will broker the exchanges necessary between your domain model and your view models to populate the view models with data. These data exchanges that the controller brokers are often achieved by using another layer such as a repository, infrastructure, or service layer... but not necessarily. In a one-project solution, your "Models" folder might contain a domain model, and then you might have a separate folder called "ViewModels". A controller would fetch data via "the Model" and then populate the view model with the data it "received" from the model. The view model would be the underlying model for your strongly-typed view. One may wonder why a developer might even bother with using a view model if there is a simple one-to-one mapping between domain object and a view. One example is that you may need to "flatten" a domain object and its relationships. Another example might be that for an index or list page, you may need to include search filter; view models greatly simplify accommodating changes to requirements.
I'm currently developing business logic in a Controller's ActionResult function, and I've noticed it's becoming unwieldy... large... involves a lot of page ups/downs.
Code includes populating lists for dropdownlists assigned to ViewBag properties, but most of the size is taken up EF (linq to entities) and in memory processing of this.
And finally sent to a view model via Auto Mapper.
Where is the best place to move this code? In another class in the Controllers folder? Or in another class in another folder, i.e. a Business layer?
Separate you project to :
WebUI(View, Controller-A MVC Project)
Business Layer(Holds Business Logic - A class Library Project )
Data Access Layer(Holds Entity Model(May be EDMX) - A class Library Project)
A controller of WebUI project call method of business layer.
If business need data from database then, it will call Data Access Layer.
Funnily enough I answered a very similar question yesterday. In a nutshell, limit your controller to just the minimum logic to link your models with your views. Business logic, data access etc. is better placed in a separate repository.
Bappi Datta is right. Let me just explain it from my point of view.
My best practice with the libs AutoMapper, EF is:
Web - includes logic of rendering, some validation, bootstrap configuration. Calls Business layer methods and classes.
Web.Models - web models with validation attributes
BusinessLogic - business layer. Includes mappings EF Entities <---> Web.Models. Uses Data classes.
Data - Here I always put EF Models and context. Also implementation of Repository pattern could be placed there.
You need to have Repository Layer (which you mentioned you already have) and then you need to have a Service Layer which will hold all your necessary business logic probably using patterns like Command Factory and Facades. Then in order for you to have a flexible and easily pluggable architecture, you need to use Dependency Injection between all layers.
Read about MVC architecture in my perspective
There can be different If's and But's in the theoretical discussion of overall MVC architecture itself. But generally your controller actions needs to be thin, you business logic needs to be in a different layer other than repository.
working on asp.net MVC from quite some time now
today stuck on a theoretical problem
going through some sample code on MSDN
I read something like this
public class SomeController()
{
public ActionResult SomeAction(SomeModel model)
{
var dataContext = new SomeDataContext();
//basic CRUD operations on data context
//
}
}
here the database obviously is being accessed through the controller and by theory is incorrect
is there something wrong with this example or my definition of what a model and what a controller is needs to be refreshed
UPDATE:-
or there is a possibility that every where on MSDN Models and ViewModels are considered equal
intro
MVC design pattern is quite old. It was originally defined for Smalltalk-80 applications, when "web" was two guys sending ping between universities. Since then it has evolved quite a lot.
The core principle behind MVC design pattern is Separation of Concerns. The pattern separates presentation from business logic. Presentation layer contains mostly views, controller, templates, viewmodels and presenters (depending on which flavor of MVC-inspired patterns you use), while business logic is ends in the model layer.
The model layer, while not strictly defines in the pattern, in ASP.NET MVC consists of services and all the structures that are used by service (including the Model Objects, better known as domain objects).
regarding the question
It is quite common to see DataContext uses in controllers, when you are looking for basic MVC tutorials. MVC architecture is meant of large scale applications, and in a Hello-World example a fully realized MVC architecture would look like just bloat.
The examples sacrifice code separation for sake of simplicity. The interaction with DataContext is basically storage logic, which is one of tasks that model layer handles. When used in controller, it means that your model layer has begun leaking in the presentation layer, and you end up with "Fat controller, skinny model" problem.
In a real world application the DataContext would be part of structure that deal with persistence within model layer. Probably as part of data mappers, if you opt to write them manually.
regarding "update"
The model (I suppose in this case you meant Domain/Model object) is from completely different application layer then ViewModel.
As the name implies, in MVVM pattern the ViewModels replace the Controllers. ViewModel acquired data from model layer, and then transforms it in such a way that is usable for View.
This pattern is best used (if you are really using MVVM) in situation when you do not have full control over behavior over Views or/and Model layer. For example: if you were hired to build an alternative frontend for SAP or when the view is actually some form of hardware device, which expects specific type of input.
The Models are typically the data classes (representing the database tables). The View Models are typically referred to as classes that have been created in order to use them in the view for presentation purposes.
You wouldn't be able to use the DataContext on a View Model in the above case, but you can use it perfectly fine with the above mentioned Model classes (also called DTO classes).
MVC is a GUI pattern, just like MVP or MVVM, it has nothing to do with data access and persistence. It's true that many simple CRUD applications are not much more that MVC and an underlying database, but in more complex applications MVC would be part of the presentation layer.
The DataContext as an O/RM belongs to the infrastructure layer, not the GUI. In MVC the Model can be understood as ViewModel, yes.
Nevertheless the controller can use the DataContext or any other means to retrieve this model from the underlying data store.
I read a couple of articles which defines domain model (as in MVC) as something that holds business logic. I never considered a model to hold any methods other than the model properties.
I would like to know if actually there is a thought which supports having functions and business logic in the domain models.
Thanks in advance.
Of course business logic should be inside domain models. But, domain models are more than just entity framework entities. Domain models consists of many small classes which reflects business domain.
In my typical MVC application, I usually split some type of business logic into these (but not limited to):
ViewModels which responsible for model for view.
Controllers which is thin and responsible for application flow.
Simple business logic such as required field can exist as attribute within entity framework model or ViewModels.
Complex business logic such as place order, booking ticket are promoted to be its own class such as PlaceOrderOperation or PlaceOrderCommand.
Simple query logic might be inside the Controller or short extension method to DbSet<Entity> type.
Complex Query also promoted to its own class such as GetMostPorpularProductsQuery assuming that the query is complex.
Infrastructure components may be extension to Entity Framework or MVC components such as ActionFilter, CustomRoute, CustomTemplate or its own classes such as EncyptionHelpers etc.
Conclusion
Building domain Model is more than just creating classes prefix with BusinessLogic such as UserBusinessLogic or with Services such as UserServices. It should consists of many small classes which responsible for one thing. Of course, you would require some usage of design patterns, choice of frameworks, infrastructure components such as error handling, localization, caching, etc.
Welcome to the trade-off world. :)
An MVC Model can indeed have business logic. MVC responsibilities been discussed in more depth here and here is a discussion on anemic domain models - this might help clear things up for you?
From MSDN:
Models, which is provided for classes that represent the application
model for your MVC Web application. This folder usually includes code
that defines objects and that defines the logic for interaction with
the data store. Typically, the actual model objects will be in
separate class libraries. However, when you create a new application,
you might put classes here and then move them into separate class
libraries at a later point in the development cycle.
What might be confusing the issue is that many ASP.Net MVC implementations use View Models, which are classes used to transfer presentation tier data between View and Controller.
In a typical large project setup, we usually delete the Models folder, and instead move our EF data layer, Entities, and business / service logic into separate assemblies entirely.
Based on my experience best place to place business logic is layer between controllers and models. Try some popular patterns, like repository or tasks/commands.
Say you have an ASP.NET MVC project and are using a service layer, such as in this contact manager tutorial on the asp.net site: http://www.asp.net/mvc/tutorials/iteration-4-make-the-application-loosely-coupled-cs
If you have viewmodels for your views, is the service layer the appropriate place to provide each viewmodel? For instance, in the service layer code sample there is a method
public IEnumerable<Contact> ListContacts()
{
return _repository.ListContacts();
}
If instead you wanted a IEnumerable, should it go in the service layer, or is there somewhere else that is the "correct" place?
Perhaps more appropriately, if you have a separate viewmodel for each view associated with ContactController, should ContactManagerService have a separate method to return each viewmodel? If the service layer is not the proper place, where should viewmodel objects be initialized for use by the controller?
Generally, no.
View models are intended to provide information to and from views and should be specific to the application, as opposed to the general domain. Controllers should orchestrate interaction with repositories, services (I am making some assumptions of the definition of service here), etc and handle building and validating view models, and also contain the logic of determining views to render.
By leaking view models into a "service" layer, you are blurring your layers and now have possible application and presentation specific mixed in with what should focused with domain-level responsibilities.
No, I don't think so. Services should care only about the problem domain, not the view that renders results. Return values should be expressed in terms of domain objects, not views.
As per the traditional approach or theory wise, ViewModel should be part of User interface layer. At least the name says so.
But when you get down to implementing it yourself with Entity Framework, MVC, Repository etc, then you realise something else.
Someone has to map Entity/DB Models with ViewModels(DTO mentioned in the end). Should this be done in [A] the UI layer (by the Controller), or in [B] the Service layer?
I go with Option B. Option A is a no no because of the simple fact that several entity models combine together to form a ViewModel. We may not pass unnecessary data to UI layer, whereas in option B, the service can play with data and pass only the required/minimum to the UI layer after mapping (to the ViewModel).
But still, let us go with option A, put ViewModel in the UI layer(and entity model in Service layer).
If the Service layer needs to map to the ViewModel, then the Service layer need to access ViewModel in UI layer. Which library/project? The Viewmodel should be in a separate project in the UI layer, and this project needs to be referenced by Service Layer. If the ViewModel is not in a separate project, then there is circular reference, so no go. It looks awkward to have Service layer accessing UI layer but still we could cope with it.
But what if there is another UI app using this service? What if there is a mobile app? How different can the ViewModel be? Should the Service access the same view model project? Will all UI projects access the same ViewModel project or they have their own?
After these considerations my answer would be to put the Viewmodel project in Service Layer. Every UI layer has to access the Service layer anyways! And there could be a lot of similar ViewModels that they all could use (hence mapping becomes easier for service layer). Mappings are done through linq these days, which is another plus.
Lastly, there is this discussion about DTO. And also about data annotation in ViewModels. ViewModels with data annotations(Microsoft.Web.Mvc.DataAnnotations.dll) cannot reside in service layer instead they reside in UI layer(but ComponentModel.DataAnnotations.dll can reside in service layer). If all projects are in one solution(.sln), then it doesn't matter which layer you put it. In enterprise applications, each layer will have its own solution.
So DTO actually is a ViewModel because mostly there will be one on one mapping between the two(say with AutoMapper). Again DTO still has the logic needed for the UI(or multiple applications) and resides in Service Layer. And the UI layer ViewModel(if we use Microsoft.Web.Mvc.DataAnnotations.dll) is just to copy the data from DTO, with some 'behavior'/attributes added to it.
[Now this discussion is about to take an interesting turn read on...:I]
And don't think data-annotation attributes are just for UI. If you limit the validation using System.ComponentModel.DataAnnotations.dll
then the same ViewModel can also be used for front-end & backend validation(thus removing UI-residing-ViewModel-copy-of-DTO). Moreover attributes can also be used in entity models. Eg: using .tt, Entity Framework data models can be autogenerated with validation attributes to do some DB validations like max-length before sending to the back end. This saves round-trips from UI to backend for validation. It also enables back-end to re-validate for security reasons. So a model is a self-reliant validator and you can pass it around easily. Another advantage is that if backend validation changes in DB then .tt (reads DB specifics and create the attribute for entity class) will automatically pick that up. This can force UI validation unit tests to fail as well, which is a big plus(so we can correct it and inform all UIs/consumers instead of accidentally forgetting and failing). Yes, the discussion is moving towards a good framework design. As you can see it is all related: tier-wise validation, unit test strategy, caching strategy, etc.
Although not directly related to the question. 'ViewModel Façade' mentioned in this must watch channel 9 link is also worth exploring. It starts exactly at 11 minutes 49 seconds in the video. Because this would be the next step/thought once your current question given above is sorted out: 'How to organize ViewModels?'
And Lastly, many of these model vs logic issues could be resolved with REST. Because every client can have the intelligence to query the data and get only the data that it needs. And it keeps the model in UI, there is no server/service layer model/logic. The only duplication then will be on the automated tests that each client need to perform. Also if there are changes in data then some clients fail if they do not adapt to the change. The question then is, are you removing service layer altogether(and the models they carry) or pushing the service layer up to your UI project(so model issue still persists) which calls the REST API. But in terms of the responsibility of Service layer, they are the same regardless.
Also in your example "_repository.ListContacts()" is returning a ViewModel from repository. This is not a mature way. Repositories should provide entity models or DB models. This gets converted to view models and it is this view model that is returned by the service layer.
This has come a bit of an "it depends" where I work - we have generally had a controller consuming some service(s) - then combining returned DTO's into a 'ViewModel' that would then get passed to the client - either via JSON result, or bound in the Razor Template.
Thing is, about 80% of the time - the mapping of DTO to ViewModel has been 1-1. We are starting to move towards 'Where needed, just consume the DTO directly, but when the DTO and what we need in our client/view don't match up - then we create a ViewModel and do the mapping between objects as needed'.
Although I'm still not convinced that this is the best or right solution - as it ends up leading to some heated discussions of 'are we just adding X to the DTO to meet the needs of the view?'
I suppose that depends on what you consider the "services" to be. I've never really liked the term service in the context of a single class; it's incredibly vague and doesn't tell you much about the actual purpose of the class.
If the "service layer" is a physical layer, such as a web service, then absolutely not; services in an SOA context should expose domain/business operations, not data and not presentation logic. But if service is just being used as an abstract concept for a further level of encapsulation, I don't see any problem with using it the way you desribe.
Just don't mix concepts. If your service deals with view models then it should be a presentation service and be layered over top of the actual Model, never directly touching the database or any business logic.
Hi I see very good answers here.
And for myself I do an other aproach.
I have to kinds of models , one is viewmodel and the other is shared models. The viewmodels stays on the UI layer and the shared models stays on a separate project.
The shared models can theoretically be used anyware because those are standalone.
This models provides some abstraction if you want to return specific data from your service layer or if you need something specific from your repository.
I don't really know if this is a good aproach but it works so well on my projects. For example
When I need to provide some information to create new objects to the database i can use the shared models directly to the service layer it saves me some complexity.
The shared models needs to be mapped sometimes , but you can ensure that your service is not leaking inesssary data to the UI.
You can see shared models as an extension but not to build your UI logic with it, you should have viewmodels to do that.
You can combine viewmodels with this shared models to save you time you can use inheritance.
The shared models has to be neutral and should not have any kind of logic.