My application currently follows a service pattern, where the models are thin and mvc-blind, and the controllers call Services that retrieve data from the model.
Right now my controllers construct and consume ViewModels based on the data that they get from the Services or Client.
What I'm wondering is - would it be wise to relocate the ViewModel classes to the service layer?
Before:
Controller asks service for data
Controller accepts data and constructs viewModel
Controller sends viewModel to client
Client sends data back to Controller
Controller takes data from viewModel and sends it back to Service to update db
After
Controller asks service for data
Service constructs a viewModel and populates it with data
Controller accepts viewModel
Controller sends viewModel to client
Client sends data back to Controller
Controller forwards viewModel to Service
Service pulls data apart and performs updates/queries as needed
Is one better than the other? Why?
Before is the better approach. Your view model should be a model of your view, as the name implies.
It may contain data retrieved by a service, but it's likely to also be augmented with additional data required for that specific view.
Also, the view model is likely to be UI technology specific, whereas the service should be completely UI agnostic. The service code is likely to be reusable across UI technologies, but the view model code is likely not to be.
In fact in a fat client application, your view models are likely to be more than just data transfer objects, but will also contain presentation logic as well as manage user state etc. Your service code will most likely not be tied to a specific client implementation.
Related
I am designing solution strucure for an application. I am planning to use Domain driven design. Asp.net MVC and Entity framework. Need your inputs in some areas.
Data Access is designed using Entity framework code first
Reposirotires are built on top of EF Data Acces
Domain model is designed usind domain model on top of Repositories
Application serveices are built on top of Damain layer
UI is developed on top of Application services
The flow is
UI (controller) --> Application service --> Domain Layer --> Repositories --> Data Access --> Data base.
I am not very clear of how to share the data in between the layers.
My Domain model can be used to sahre data between Repositories, Data Access and Domain Layer. I am just thinking the way the data should be passed from Daomin Layert to Application Service and Application Service to UI. I can use DTOs, But not sure weather it is a good option or not, as i have some models are already in Domain Model, View model in UI.
Reuse Domain Model or UI Model is not good, it will make your layers are tightly coupled. It's very difficult to develop large scale applications that way.
What you think is correct, Application is a thin layer, it's just a bunch of Actions which will be called directly from UI layer and information will be passed through an object called ActionParameter. ActionParameters are defined in Application layer and ActionParameter objects are constructed on UI layer and passed to Application layer.
Application will retrieve data from DB via Data Access Layer. An Query Action sometimes need to fetch data from many source, different domain entities and data need to be projected, transformed or formatted before return to UI layer. We will have something like ActionResult objects that contains all data to be returned to UI layer.
It seems there will be a lot of codes but I think it's necessary. Each layer has its own purpose and when we change one, other layers won't be impacted.
Given the flow you describe, create view models in the UI layer to be instantiated by the controller. A view model is simple object to which the view binds. This should be decoupled from the underlying domain model to address concerns noted by namkha87.
As far as the data access layer, you can use the domain objects themselves for object-relational mapping since EF allows this. There is no need for an intermediate DTO here.
Another thing to consider is separating the model used for queries from one's used to invoke behavior. This way, you can ensure that an application service never exposes behavioral domain objects, only read-models. The problem with having an application service expose domain objects to outer layers is that it will allow those outer layers to invoke behaviors on those objects the results being undefined. When you only return read-only objects with no behaviors, this isn't a problem. For data coming back, don't have the UI layer created domain objects directly - you should distinguish between entities and simple data.
Right now I have a few layers to my project: Core <> Repository <> API... and I'll be building a "client" MVC web project layer. My question is - where do viewModels belong in this architecture?
Should the controller methods of the Web Project call the API (multiple times - getTheseObjects, getThoseObjects) to get data, and then build the viewModel? Or should the API support calls to construct the viewModel so that only one API call (getAllObjectsForThisPage) needs to be made per page for the application?
Your view models will belong in your client MVC app. They will be specific to the views in that individual client application, and usually will get populated by domain objects.
This is how it can work: the controller mediates the https requests thus calls a API endpoint and receives some data or domain objects, which in turn you use to populate your view models.
Take a look at automapper if you are returning domain objects from your api, it really helps with mapping domain object to view models.
You can place ViewModels into your MVC application, but you could create something that is called DTO (Data Transformation Object) and return that from Web API to your client. In essence it will be a class with only the necessary information that you pass to the client. If you want to call that ViewModel you might as well go ahead and call it like that. My suggestion would be to issue one call and to return all the necessary information. One call one trip.
My practice usually is to separate ViewModel from MVC and store it in some other project. The service layer would prepare a ViewModel and return it to MVC. The reason for this is that once I had a requirement to build WPF application after MVC was completed. It was quite a pain moving things around and retesting everything to make sure that it still works fine.
I have a complex User Control that contains some views, each have its own ViewModel.
My question is how can all of these ViewModels share some data (for example an observable collection) without each one have a separate call to the service?
The service should be an abstraction of the data. Whether that data is pulled from a WS, DB, etc...should be irrelevant. Each ViewModel can contain a property which will be bound to by the View. That property can be an ObservableCollection<T> which wraps a call to the service. That data may in fact be cached via the service and only update periodically but either way it will push the data to a single point of reference for retrieval amongst the ViewModels.
Normally in the MVC Pattern, when a user clicks on a page the request would be sent ,then controller would handle the request ,then process it using the model and route it to the appropriate view.
I have read the post about the passive model and active model,but is there a possibility where the view directly interacts with the model, would that be a bi-directional relationship (i.e Model<->View) or one-directional (i.e Model->View).
Is it appropriate to have a relationship between Model and View? Well in a ASP.NET MVC project should i have a relationship between model and view, or have it independent of the model?
I think it's almost always preferable to have your views be model-specific, that is, strongly-typed. Where models share related data, you can reuse partial views that are specific to that subset of data. In ASP.NET MVC, your model is -- or should be -- ignorant of the view since they only way they can interact is through a web request, which is a controller function. No you may say that you could interact through web services, but I would consider those to just be another flavor of controller. In fact, with MVC, I see very little need to develop a separate web service at all, using REST-based controller actions instead.
I always see the View as the way to present the Model. According to this point of view, the View is Model aware and in ASP.NET MVC you should inherit pages from ViewPage to avoid abusing from ViewData or castings.
With that in mind, the Model is not view aware and is just an object that is used from the view to present data to the user.
Finally, you can share the same Model from different Views, for example an XML output can share the same model as the HTML output but the views can be very different.
The cycle is more or less, Controller generates Model, passes it to the View, that shows de Model and in case there's interaction, posts the input to the Controller and the cycle starts again.
In Java Swing MVC is implemented as the View and Controller combined, with a View that both reads from the model and registers for events from it which effectively makes them loosely dependent on each other.
Usually web applications don't do this as the real view is rendered on the client and can't receive events from the model as easily, so in those cases the relationship only goes one way. Its certainly not a bad thing to have a relationship between the model and the view as long as the Model does not dependent directly on and view classes. In that case a dependency cycle would be set up and that harms maintenance and especially testing.
For example the way this is achieved in Swing is via a Listener interface, which the view can then implement/provide an implementation of to the model.
Should the Controller make direct assignments on the Model objects, or just tell the Model what needs to be done?
The controller has two traditional roles:
handling the input event from the UI (registered handler or callback)
notifying the model of an action--which may or may not result in a change on the model's state
It does not perform data validation, that is on the model, nor does it have any say in how information is presented.
It depends largely on the scope of your application. If it's relatively quick and dirty, then there's no sense in over-engineering, and sure, your controllers can talk to your model objects. On the other hand, if it needs to be more "enterprisey" for whatever reason, a good pattern to use in conjunction with MVC is the so-called "Business Delegate". This is where you can compose coarse-grained methods out of one or more methods on one or more model objects; for instance deleting an object and then returning a refreshed list without that object. This layer gives two advantages. For one, it decouples the controllers from whatever ORM system is being used for model objects. Furthermore, it is the layer that finally must constructively deal with any exceptions that may have occurred instead of re-throwing them.
I don't think a controller should be dealing with model objects.
I tend to think that controller is really part of the UI tier. I prefer to inject a service layer in-between the controller and the rest of the app. The web tier accepts HTTP requests, unmarshals parameters from request objects into objects that the service interface can deal with, and marshals the response to send back. All the work with transactions, units of work, and dealing with model and persistence objects is done by the service.
This approach is more service oriented. It separates the service from the user interface, leaving open the possibility that several clients can reuse the same service. It makes the layer that marshals requests to the service "thin", so it's easy to switch out SOAP services for REST or EJB or CORBA or whatever the next new thing will be.
The Model services don't have to know the existence of the controller, thus, controller can do the stuff what ever the view needs by utilising the model services.