I have been studying various patterns for layering an MVC application and need a little advice. What I currently have is the following:
1) POCO Domain Model, no business logic at all, so basically an anemic Domain Model.
2) EntityFramework with a Repository layer that hands back Domain objects.
3) Service Layer, now I am not sure if this an Application Service Layer or Domain Service Layer, but basically it is an API against the domain model. All of the business logic resides in this layer and assures the domain objects are valid, then hands it off to the repositories to be persisted via EF back to the DB.
4) ASP.NET MVC Application, this application talks to the service layer to get the objects it needs.
I like how this works as it provides a single point of interaction with the domain model, but what I think I need is a layer in between the service layer and the mvc application. The responsibility of this layer would be to transform domain objects to and from view models that the controller could interact with to get the exact data the view needs, and to provide the populated domain objects back to the service layer. Would this be the Application Service Layer and the service layer mentioned above is the Domain Service Layer?
I use AutoMapper to get the domain objects into view models, but I am not sure of the standard of getting them back to a domain object.
Any advice or ideas would be great.
While in theory, your Domain Layer (especially if you are using POCOs) classes are perfectly fine to use in Controllers and Views, in practice, there are always these corner cases and differences.
Typically, objects that controllers and views deal with are simplifications of your Domain Model POCOs or different aggregations of your POCOs from what your Application Service Layer provides/understands.
Therefore, I would not recommend building a separate layer and instead I would recommend adding methods to your View Models to your Domain Layer objects to be sent to your Application Service.
For example, if you have User Domain Level class and UserModel View Model, I would advocate creating User ToUser() instance method on and UserModel UserModel.FromUser(User user) static method to deal with conversion.
You can also mix and match other View Models in there to be able to create Domain Objects.
Related
In a three-layered architecture, where is the DAO pattern located? Is it in the business logic layer or in the data layer?
I'm not sure that thinking in terms of layering is useful anymore.
We used to have 2-tier client-server, with all the logic in the client and a database running on a server.
We evolved to 3-tier, usually associated with MVC model-view-controller. There wasn't a mention of data access objects in the original Smalltalk MVC pattern.
Now I think view and controller generally go together, splitting rendering of the user interface between client and server. Controllers have business logic and interact with many web and data access services. Data access objects would be used by controllers to deal with data sources. Call that whatever layer you wish.
I don't think of microservices as a layer. Perhaps the usefulness of the concept has diminished.
I haven MVC app, with "M" including Service and Repository layers.
However, I am a little confused as to where and how to do a couple of things.
One Service calling two repositories, or calling it's own repository and another service
e.g.
I have a ReferenceDataService, which handles all of the logic for CRUD with my reference tables.
Then in my "CustomerService" I need to 'R' my reference data to get e.g. Description instead of Id. So, do I call the ReferenceDataService or ReferenceDataRepository?
At some layer I'd like to map from Entity to ViewModel.
Do I do this in my Service layer, or in the Controller?
e.g. Does my ServiceLayer do the mapping/logic from VM to Entity and back?
Thanks:)
Repositories talk to an underlying data source.
Service layer talks to repositories with domain models. It takes/passes domain models from/to the repository layer.
Controller talks to service layer. Controller takes/passes domain models from/to the service layer.
Controller calls mapping layer (if any) to map between the domain models and view models. If you don't have a mapping layer you could do the mapping in your controller although this could quickly become cumbersome in which case AutoMapper could serve as a very handy mapping layer.
Another more simpler scenario is when you don't need a service layer which is often the case in smaller applications. A service layer brings no benefit. So the controller talks directly to the repositories with the domain models.
ViewModel contains data, required for displaying model on view. If you'll use another view (e.g. mobile application, or desktop application, or even web service) you will require another data to be displayed on view. If you'll do mappings on service layer, then you will not be able to use it with another type of application. Thus controller is a place where you map domain data to display them on view (whatever type of view you have).
I'm trying to architect my MVC web project and I'm running into a bit of a problem.
I am using EF4.1. I've created a DataAccess project with the EDMX file. Then I use the dbContext generator to make my POCO .tt classes.
As it is right now, my Business logic layer can access the POCO classes just fine, but the presentation layer cannot.
I think that I'm supposed to create another level of abstraction and put the dbContext .tt files into their own project so that both the BusinessLogic layer and the Presentation layer can access the POCO classes, but only the BusinessLogic has access to the entity framework. The presentation layer shouldn't need to know anything about EF.
Something like this...
POCO Classes - DataAccess
| |
|---------Business Logic
| |
|_________Presentation
Am I on the right track here, and if so, do I simply cut/paste the .tt files into the new project or is there a way to force the dbContext add-on to create these in my other project?
Your presentation layer doesn't have to know anything about the EF. Just reference that project from your presentation layer to access the models.
However - your presentation layer shouldn't ideally be using any of those POCO models. They should be using ViewModels. I dont necessarily believe in the DTOs here as DTOs have a specific purpose. Your repository/data access can return models but generally those get returned to a service layer. The service layer then would return your ViewModel representation to your controller.
This sets you up nicely for dependency injection as well, since into your controller you just inject your service layer. Into your service you can inject then any repositories you need, and so on.
Ironically I think I may be working on a book for this exact subject shortly : )
Consider sending Data Transfer Objects between your Business Logic and Presentation layers. This would allow you to shape the data for your views and and prevent information from leaking into the Presentation layer (e.g. if you have a field in your POCO that is needed for your business logic but doesn't need to be available in your Presentation layer).
The question is, how would you move data to and from the
presentation layer? Put another way, should the presentation layer
hold a reference to the domain model assembly? (In an Entity Framework
scenario, the domain model assembly is just the DLL created out of the
EDMX file.)
From a pure design perspective, DTOs are a solution really close to
perfection. DTOs help to further decouple presentation from the
service layer and the domain model. When DTOs are used, the
presentation layer and the service layer share data contracts rather
than classes.
A layer of DTOs isolates the domain model from the presentation,
resulting in both loose coupling and optimized data transfer.
If you go this route, also check out Automapper to help with mapping your DTOs to POCOs and vice-versa.
So there are several ways to structure your project. What you are referring to is one way, in which you share poco's between all layers.
Another way is to have your POCO's be in the data and business layer, then create a similar object model that's shared between UI and business layer. Finally, you might also create a third model for the UI only called teh ViewModel.
It all really depends on your needs. If your object model is very complex, then you might need to simplify it with ViewModels.
In the MVC pattern, the controller is the least reusable, compared to the other two aspects.
Now let's say I have an app (say for Ordering Pizza), which is available both as a web app and a mobile app (say iPhone). So in that case, I think the model (or data) can be reused. The view might not be reusable.
But regarding the controller, is it possible to reuse anything? Let's say if I already have a working web app, can I reuse controller logic for the mobile app as well? Also, what is and where exactly does "business logic" reside in MVC?
The controller calls a service layer. The service layer uses the model to do business logic. Controller never contains business logic. It should only delegate work to the service layer. I consider the service layer as the part that the domain model exposes, you could say it is the "Model" in MVC.
That said, I don't think the MVC frameworks really care if the controller is reusable or not. The important part is the model, which should not change because the service layer code is reused. Besides, if we write our code correctly, the controller will be a very thin layer and reusability should not be a concern.
Can you reuse the controller logic from the web app for a mobile application? I think not, but you could use the service layer. I am sceptical if even the view can be used directly from web to mobile apps, the needs are so different.
I suggest you look at Domain driven design if you are interested in application design and learning how to organize business logic.
Both of them are based from mvc.
But in 3-tier architecture,storage layer is a separate layer,
while in symfony framework,database(storage) level is included in model layer.
Why are they different?
I would say that MVC is focused on user-interaction. It describes how to develop a rich and flexible system that reacts to user requests, but says nothing about what happens below controller layer.
It just says:
user sends a request;
dispatcher forwards request to appropriate controller;
controller retrieves models, but it's not specified HOW: using model's methods, using a DAO layer, using a Managers layer, whatever;
controller forwards to a view.
CakePHP also has model and data layer glued together, as many others. It's just a choice: this way you have less layers and less code, but in case you change your mind you'll have to modify all your code, directly in the models.