ASP.NET MVC vs. nTier Separation of Concerns - asp.net-mvc

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.

Related

MVC project setup at the enterprise level. What's expected?

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.

Is it a good aproach to make a difference between domain models and MVC models?

(I am a very beginner in MVC)
I mean to have a business logic layer with the domain models and an application service layer with view models and controllers obtaining view models only from application service methods. Controllers doesn't contain any logic and the MVC models are the view models (from the app service layer) which contains logic only related to displaying.
Any tutorial I have seen on ASP.NET MVC focuses on having logic in controller classes, but I think in this way (in a large app) you can duplicate business logic, writing redundant code.
Is it a good approach to make a difference between domain models and MVC models
Definitely, I always separate my domain models from my view models because, like you, I agree that domain models don't belong in the controllers.
Controllers in an ASP.NET MVC project are effectively view controllers and as such shouldn't really contain business logic. Using a service layer is generally the best way to manage communication between your presentation / business layers (like you appear to be doing anyway).
Yep, its a good idea to keep them separate. The way I've seen it done is that you have your "Business Objects" namespace, then your 'View Models' namespace. The objects in the 'View Models' namespace are the Models for MVC and usually contain a mix of regular types and instances of business objects.

ASP.NET MVC - Model can have business logic?

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.

Having MVC controllers light and models heavy

I have heard that the controller should be kept light and models heavy.
I am somewhat confused about the best practice on what should be kept in the controller and what should be kept in the model.
In our organization, we use Entity Framework where and put the tables there.
For the controller, we use LINQ and then send the info over to the view.
Kind of confused on what code should be in the Controller and in the Model.
DisclaimerThe whole topic is a giant mess. Especially when it comes to Web MVC. For all practical purposes it is impossible to use classical MVC pattern for web, because the view should be observing model. Theoretically you could implement something like that with WebSockets, but keeping a persistent model for each user is not a realistic solution.
Here is what you must know about MVC
The most important idea in both classical MVC and MVC-inspired patterns Separation of Concerns. It divides the application in two major layers:
Presentation layer
Governs the user interface. It deals with both creation of the interface and reacts to the user's manipulation of this interface. This interface might be GUI for a desktop application or HTML web page, but it also can be REST API or receiver-responder on a Mars rover. This is why a web application can implement MVC pattern in both frontend and backend.
The mandatory parts are views and controllers, but, in context of web, fully realized views usually also use multiple templates to create the interface.
Model layer
This is where all the business rules and logic lives. The M in MVC is not a single entity. Instead it is a layer, which contains different structures. Some of those structures are also responsible for interaction with storage.
What are the responsibilities of controllers ?
Controllers are part of presentation layer, which deals with user input. In context of web-based implementations, you will usually have 1:1 relationship between views and controllers, where controller receives the requests from browser and, based on the content of said requests, alters the state of model layer and view.
If you are using classical MVC or Model2 MVC, then that is the extent of controllers responsibilities.
In MVP and MVVM patterns, where you have a passive view, controller-like structures are responsible for acquiring information from model layer and passing it on to the current view instance. This post might provide some additional details on the MVC-inspired patterns.
But the controller is in no way responsible for any form of business logic. If it was, it would mean, that you have a leaking abstraction, because the structures of presentation layer would be doing work, which should be in the model layer.
Usually the controllers will the be simplest structures in you application.
What about the model ?
As mentioned before, model is a layer, which encompasses all of the domain business logic and related functionality. This layer , just like presentation layer, is made up from multiple groups of structures:
Domain Objects[1]
These structures are usually what people mean, when talking about "models". They are also known as model objects or business objects. This is where most of domain business logic ends up.
Data Storage Structures
This group would contain all of the classes, which abstract the interaction with storage (SQL databases, caching systems, noSQL, remote SOAP or REST APIs). They will usually implement some variation of data mapper or repository pattern , but you could be using some other solutions too, like unit of work. The implementation details are not so important. What is important is that they let you store data from and retrieve information into your domain objects.
Services
Or you could call the "components". There are high level abstractions in your model layer, which facilitate the interaction between domain objects and storage structures. The usually represent large chunks of model layer, like "recognition service", "mailers", "article management", and will provide the interface for presentation layer to interact with.
That's something of a religious debate.
Some like as little as possible code in their controller and other as little as possible in their model.
Do what feels natural to you in the project, but be consistent within it.
All else is dogma you can pick an example either way and make a case.
Model is the core of your application. It is best to think of models as of your business entities. Do you want to create a view of an invoice? Then Invoice be your model, it represents the underlying object.
Controller is just a way to handle requests from a client, retrieving the data from database (or updating them) and flushing out the responses.
Your thoughts about the application design should be model-centric, that's the important part.
In simple terms, Model represents the underlying data that your application will be using. It is to be designed in a way that it can be used across different applications.
For example, A model to represent News data can be used by console commands, Web service etc.
It is in model where you will have ur business logic defined, independent of the view.
Controller can be thought of as glue that binds Model and View together. They deal directly with client requests and accordingly interact with views and models.
In a well designed application, you data structure and business logic will be designed in a
Model, making it "heavy". While Controller will just interlink your model and view with the client requests, making it "light".
In the classic Model-View-Controller MVC pattern, your Model is essentially a "headless" application, with no UI and is completely UI-agnostics. It offers an API that is the functional core of the application.
The View is the user interface, however you choose to define it (web page? elevator control panel? something else?). A given application might have 1 view or it might have many views.
The Controller (or Controllers — like Views, you might have one to many Controllers for a given application) relays and transforms events, notifications and data between View and Model so as to preclude the Model from needing to know anything that is View-specific.
The idea is to isolate the core application (the Model) from the user interface (the View). From that some things follow:
The View is aware of and communicates with both Controller and Model (you're unlikely to try to wire up the View to another Model) and expected for the Controller to be aware of both View and Model.
The Controller is aware of and communicates with both View and Model.
The Model knows nothing of Controller or View.
Code that performs business logic should be in the Model, not in the Controller.
I'm no MVC expert, but try and concentrate on the fact that the controller should use the input from the user to direct them to the correct view.
I don't know if NerdDinner is an ideal example, but you can see Scott Hanselman et al does a little bit of data access from his EF context but pushes most of the other logic to service classes or helpers on the model.
I don't know if I agree with the 'models heavy' part, as I don't use the models as 'business objects'. If I really need a lot of 'business' logic, I will typically create that in a separate 'Domain' layer and may even have a separate Data Access layer on top of this. But for a lot of simple (see: non-enterprise) projects, this is overkill in my experience.

Where are the Business Rules in MVC

Now that everyone is talking about MVC, I notice that the business rules are not being addressed. In the old days of the 3-tier architecture, The business rules were in the middle layer. Where do they fall in the new MVC?
The reason you never see MVC address "Business Rules" is that MVC by and large is a presentation pattern. It's focused on how to structure your application. The Model, for example, can be thought of as a presentation model. The model of your application, which the view then renders.
However, in order to create the presentation model, you generally need to go to your domain models where all your business logic lives. At that point, MVC doesn't dictate where that code physically live. Is it on another tier? MVC doesn't care.
At first brush, I'd say they belong in the model. The MVC Entry on Wikipedia seems to agree: "In MVC, the model represents the information (the data) of the application and the business rules used to manipulate the data".
After all, by 'Business rules' we mean the functional algorithms and logic that encode the domain that your application is involved with, as opposed to input/output related logic. These core business-related logic does not - or should not- change based upon what is being displayed to the user (which is the domain of the View) or the user input (which is primarily received by the Controller).
In my experience, asking this sort of question has been very revealing during the software development process: we found a large number of things that were considered 'business rules' by some people, but turned out to be something else. If it is not a true business rule, it might not belong to the model.
Business rules always live in the model. The model is the bit that you could resuse with a completely different UI. The view is obviously completely dependent on UI choices and the controller has to take data from the model and tell the view to render it.
Putting business logic into the view is bad because it ties the structure to the presentation.
Putting business logic into the controller is bad because it splits your business domain between the data persisted by the model and the rules in the controller.
A quote from a Wikipedia Article:
MVC is often seen in web applications, where the view is the actual HTML page, and the controller is the code that gathers dynamic data and generates the content within the HTML. Finally, the model is represented by the actual content, usually stored in a database or in XML nodes, and the business rules that transform that content based on user actions.
Is there any reason why you cant mix MVC and Ntier? Our application does just that. Our controllers are used for data validation and decide which Business Layer calls to make.
OurApp.Web - Asp.net MVC Project
OurApp.Business - Business Layer Library
OurApp.DataAccess - Data Layer Library
OurApp.Entities - Basically all the 'models' shared by all layers
Business rules should be in the model, NOT the controller. The controller and view are part of the presentation layer.
The model represents the domain's entities and functionality ..
The controller is merely a manager for taking user input and requests, performing actions in/on the model and mapping that to views in the presentation layer. The controller is not just a mediator either, the view OR controller may act upon the model.
This is an anciently posted question, but I like a rules repository to be completely independent of any part of an application. Multiple applications, multiple implementations of a business tier, should be able to access a static rendering of a business rules repository. Simple separation decisions such as this make a migration from desktop -> web, for instance, trivial.
In my architecture, View -> Model -> Controller -> Business Tier -> Rules Repository, i.e. the controller accesses coarse data as presented by the business tier/layer, feeds it to the model which massages it into a presentable form, and the view passively displays it. The business tier, which is re-usable across any presentation format, will have explicit rules and access to a subsystem with implicit rules. By design, each component is ignorant of the details of a component above it.
I think the issue is a matter of definition. It seems to me that the logic for presenting the screens in the order needed is a controller issue and I have seen some projects that use a rules engine to determine the order and what is required input from the user. This is not the same as business rules imho.
You guys are wrong the business rules live within the controller and not the model...

Resources