I've read some MVC advice in the past regarding models stating that you should not reuse the same model objects for the domain and the view; but I haven't been able to find anyone willing to discuss why this is bad.
It is my opinion that creating two separate models - one for the domain, one for the view - and then mapping between them creates a lot of duplication, plus tedious mapping code (some of which might be alleviated by things like AutoMapper) that will likely be error prone.
What makes having a separate model for the two concerns worth the trouble of duplication and mapping code?
At its heart, two models is about Separation of Concerns. I want my View to work off of a single Model. I want my Domain Model to represent the conceptual model I build with the domain experts. ViewModel often has technical constraints. Domain Model is about POCO, and not being bound by technical constraints of either data shown (View) or persisted (in a DB or otherwise).
Suppose I have three entities shown on a screen. Does that mean I need to force a relationship between the three? Or just create a ViewModel component object that contains all three items. With a separate ViewModel, View concerns are separated from my domain.
why? 'cause the view shouldn't have the ability to use the model object!
Imagine you pass the project to a web designer to do the view layer. Suddenly he/she has the ability to mess around with your application's data through the model layer. That's not good.
So always only pass the data the view needs, instead of the object with methods.
J.P. Boodhoo's article Screen Bound DTOs will help you understand the design benefit.
There is also a security benefit that I have written about.
Having a presentation model simplifies your views. This is especially important because views are typically very hard to test. By having a presentation model you move a lot of work out of the view and into the domain->presentation model. Things like formatting, handling null values and flattening object graphs.
I agree that the extra mapping is a pain but I think you probably need to try both approaches in your specific context to see what works best for you.
There are even plainer concerns including the view model's ability to be specially formatted and certainly null-safe.
I guess the idea is that your domain models might extend to other implementations, not just your MVC application and that would break the seperations of concerns principle. If your View Model IS your domain model then your domain model has two reasons to change: a domain change requirement AND a view requirement change.
Seems I have duplication of rules as well.
ie. client object validation on the UI, then mapping to domain object that has to be validated.
What I tend to do however is map my set of domain objects to create a model - ie. a webpage that shows customer info, stock info, etc... my model becomes a structure that holds a Customer object and a Stock object.
CompanyPageModel
public Customer Customer{get;}
public Stock Stock {get;}
then in my mvc project ViewData.Model.Customer.Name ViewData.Model.Stock.CurrentStocks
Separation 'seems' like more work, but later, it's good to have this division of UI/Domain model...sorta like writing tests :)
I have drunk the cool-aide finally, I do like being able to mark my viewmodel with display instructions and have that all auto wired up.
What I demand now is some kind of auto generator of viewmodels from poco entities. I always set some string as an int and it takes me forever to find it. Don't even think of doing this without automapper unless you like pain.
Related
I have just started an MVC project for the first time, and I have encountered a problem that I really wasn't expecting: Too many models.
Not too many different models, but too many which are subtly different, but almost exactly the same.
I have a fairly complex page, with several combo boxes, a list of detail objects and some other extraneous unrelated things that I need to keep track of. More information goes to the view than I get back (which is fine).
I have a domain model, which has remained constant throughout. (1 model)
I have a single use view model, which is the domain model and some extra information wrapped round it. (1 model)
I have a single use form model, which is a copy of the view model with an empty shell copy of the domain model inside it with validation stuff on it. (2 models)
I needed to change the type of a property this afternoon, and I had three separate places to change it in. It seems that I have too many models which are single use. It seems so much work for something that was supposed to be much easier than classic ASP.NET.
My question is: Am I doing it right? Are there supposed to be a multitude of models, or am I missing something obvious?
Not entirely sure what the form model in your example is for - are you using that to limit the post-able fields from the client or using that to map in to your domain?
In my own MVC websites I will have a domain model (which may just be a local domain or come from a remote WCF service) which I map one to one in to my individual ViewModels in order to render on screen and receive the post back. These also contain my validation (be it annotations or fluent etc).
Any property name changes would then be restricted to just the relevant page's ViewModel and the domain.
If you're in a situation where you're replicating properties between domain models then some sort of base view model structure would serve you well for common entities but on the whole it's not something I find to be a massive overhead personally.
Wouldn't creating ViewModels lead to redundancy? In the sense I have my domain model and I need to display the data from it on a view. So we create ViewModels, add DataAnnotations to it and display it on the View. At this point I have 2 object with almost identical data.
As others have already said, only the most trivial application can get away with passing their domain models directly to the view. Even then, it's still not a good idea for a lot of reasons.
The requirements of your view are different from the requirements for your data model. For instance, you may have a field that is required in your view, but is nullable in your vie model. If you add a `[Required]' attribute, then your model will now consider this field non-nullable.
However, my single biggest reason for never using domain models in views is for security. MVC allows you to post any value to it, and the default model binder will happily plug values you post into the model, which means if you had an IsAdmin flag, and someone posted a true value for IsAdmin, then when you saved the changes to the model, someone is now an admin.
The first rule of web security is never trust input from the user, and passing your view models directly to the view basically gives up sanitizing your data.
Yes, it is a form of redundancy. But redundancy is often required to achieve other goals. In case of Models, having this separation of view models and domain models helps in achieving a decoupled setup between your view and data-store. And it is not often that ViewModels are exact copies of Domain.
Which means, either can change without having an impact on other. I can see cases where this would be valuable - data-type changes in table need not call for deployment of the web application.
So, in summary, while there is redundancy, it is a design choice on whether the system is complex enough to benefit from this redundancy.
In 99% cases ViewModels don't lead to redundency.
The only 1% which comes to my mind is simple application with anemic domain models and pages, which shows nothing but a single model on a page. This is peculiar to content management pages.
In any other case:
1) your ViewModels will join information from multiple domain models
2) you'll have a logic specific to your domain in domain models
3) it's not a good idea to mix view-specific metainformation like DataAnnotations into your domain
Nope, using ViewModel has its own purpose. Let's think about a situation when your view has two or more Entities from the Domain Model, without a ViewModel, how are you gonna organize data? The data needed for a view sometime is not exactly like domain model, it can has
less or more information and sometime we have to pre-process data from domain before rendering view(e.g. format date time depends on client's culture).
Furthermore, ViewModel help de-couple the Web UI from the domain layer. Entities in Domain Model is not just about data representation(which is the only purpose of view model), they also have operations that mimics the business rule, you don't want expose too much domain knowledge to the UI layer who doesn't need to know.
This question really has larger architectural implications and I welcome any input or suggestions on this:
I'm more of the Martin Fowler school of thought when it comes to OOP. I believe you should be able to directly render domain entities in the UI. If I have a Car entity, I should be able to render it to a webpage. The domain model is a crosscutting concern and not a layer. Treating the domain model as a layer leads to an anemic domain model. I don't believe in DTOs in an OOP architecture.
A view model for me is a way of composing the domain entities required in your view. It's not a DTO. I don't understand what the reasoning behind using a view model like DTO is though it seems like a common thing to do using automapper?
So using the metadata approach I put data annotations on my domain model to give any UI implementation hints on how to render and validate the entities. I like to have a richER domain model.
In MVC3 how can you accomplish this (specifically using the Display data annotation) with a resource file that resides in the UI layer? Is there a native implementation for this or do I need to get creative myself? Or have I gone wrong somewhere in my approach?
I disagree.
For one thing, some of the attributes you will use to specify how an entity property should be displayed on a web page come from the System.Web namespace, not the System.ComponentModel.DataAnnotations namespace. By putting these attributes on properties in your domain model, your domain model is taking a dependency on System.Web. For example, there is the [HiddenInput] attribute that tells MVC3 to render a field as input type="hidden". This is not in System.CompoenentModel.DataAnnotations.
Secondly, I don't believe you need data annotation attributes on your entity properties to have a rich domain model. A rich domain model comes from classes that wrap knowledge in a context. The client application should not need to know anything about the domain in order to use it. You achieve a rich domain model with classes, methods, and properties that describe knowledge using the ubiquitous language. DataAnnotations attributes don't lend themselves well to the ubiquitous language imo. And, your domain is more than just your entities. There are factories, services, and other patterns that you can use to build a rich domain model. A domain with only entities and metadata sounds anemic to me.
Thirdly, you may have an entity that should be rendered in different ways on your web site. When someone searches for a car, you may want to display just the make, model, year, and thumbnail photo. When someone clicks on the search result, you may want to display multiple photos, reviews, etc. If you were to use the UIHint attribute on an entity to tell the web ui how to render the car, you wouldn't be able to have different strategies for rendering the Car in different contexts.
Finally, yes, automapper is really great for DTOing your entities into viewmodels. It essentially lets you populate copies of the entity, disconnected from the domain, targeted for specific UI concerns. Here it is safe to use HiddenInput and UIHint attributes to tell MVC3 how to render data.
Response to comment 1
As far as UIHint, I mentioned it here because it has a special meaning with MVC3 EditorTemplates. In cases where a partial view involves receiving input, what is the composition of the view? Text fields, drop-down lists, and input elements that often correspond to entities and their properties in some aggregate root. You will therefore need some representation of the entities to encapsulate the data. Your DTO can be an aggregate root as well, with depth. You can have a root DTO with scalar properties (text/date/bool), navigation properties (drop-down list) and collection properties (ul/ol/table).
We create a corresponding viewmodels for many entities in an aggregate root, and implement them as views using EditorTemplates. If we ever want to switch to a different EditorTemplate, we can apply UIHint to a viewmodel property. Thus we can tell it to "render a location dto as a google map". Automapper can map navigational and collection properties to corresponding viewmodels, forming as complex a representation of your domain entities as you need for the user.
Forgive me if I misunderstand what you mean by flat dto.
Response to comment 2
A viewmodel dto can flatten out / denormalize some properties (using automapper), if your requirements call for it. For example, consider a University entity. It may have many names in many languages (translations), hinting at a UniversityName entity in the aggregate, with University having a collection of Names (1..n). Of those names, 1 may represent the OfficialName / NativeName, and another may represent the TranslatedName to the user's CurrentUICulture. Other entities in the collection may represent TranslatedNames that the user does not understand, and need not be bothered with.
If you have a view that is only interested in these 2 Names in the collection, you can promote them to first-class properties on the viewmodel:
public class UniversityViewModel
{
public string OfficialName { get; set; }
public string TranslatedName { get; set; }
// ...other properties
}
This is a case where denormalizing part of the entity when converting to a viewmodel dto can make sense. Notice how the viewmodel is anemic -- a bare container for data transfer from a controller to a view. This is perfectly fine, and in fact, encouraged.
Answer to original question
To answer your original question, it helps if you think of your domain model & entities as a layer -- more specifically, a bottom layer. Layered software is easier to understand if you think about the various concerns in an application as having dependencies on other concerns. MVC3 is a presentation / UI layer, and will have dependencies on the layers beneath it -- one of those being your domain layer.
If you want to access a resource file in the UI from the domain layer, you are going in the opposite direction. You would be making a low layer depend on a higher layer. If your domain lib depends on the UI lib for a resource, and the UI lib depends on the domain for entities, you end up with a circular dependency. I think you could probably accomplish it using reflection if you needed to, but in that case, you would be fighting against the framework. MVC and .NET in general may not be the best choice for you if that is the case.
I actually think of resource files as a cross-cutting concern. Our application has i18n sprinkled throughout, and often we find we need the same language text resources in both the domain and the UI.
There is nothing wrong with putting a Display attribute on an entity. But if you want to use resources for it, then either put that resource in the domain layer, or if you feel it doesn't belong there, in a lower layer. That way it can be accessed by both the domain and the UI.
So I ended up putting a resourse file in the domain model and added a custom HiddenFieldAttribute so that I don't have to reference the MVC assembly in the domain model.
I still fundamentally dissagree that a view model is really a DTO and that the domain model should be constructed as a layer. I feel that architecting the application in this way creates abstractions that really have no value. If the domain model was truly a layer then we would build a set of logical interfaces from which to access it, and this we don't do. It's a cross cutting concern.
Thanks to olivehour for an interesting discussion and suggesting that it's okay to place resource file(s) in to domain model assembly.
I asked here a while ago for some help in understanding MVC, since I'm very new to the topic. I thought I had a decent understanding of it, and this is documented in a blog post I wrote recently on the subject. My understanding basically boils down to this:
Controller: Determines what needs to be done to fulfill a request, and utilizes whatever models it needs to collect/modify as needed. It's basically a manager for a given process.
Views: Presentation only. Once a controller collects what it needs, it creates a specific type of view, hands it the information, and says "show this to the user however you do it."
Models: Behavior of the application. When the controller asks it to extract or modify something, it knows how to do it. It also knows to trigger other models to do related tasks (in my understanding, when a model tries to "vote for something" on StackOverflow, that model knows to ask if a badge should also be granted because of it. The controller doesn't need to care about that).
My question, assuming all of that is more or less accurate, is where do entity objects come in? Are models and entities the same thing, with each object knowing how to persist its own data, or are entities a separate concept that exist on their own and are used throughout the application?
My money is on the latter, since this would allow models to act independently, while all three layers (model, view and controller) could utilize the entities to pass data around as needed. Also, objects and database persistence seem like concerns that should be separated.
To be honest, the more I read about MVC the more confused I get. I'm about ready to just take the core concept (separate presentation from logic) and run with it in whatever way feels right, and not worry too much about the "MVC" label.
Yes!
My money is on the latter, since this would allow models to act independently
You don't want to bind your view to an Entity, because if the view also needs some other piece of data, you would have to it to your Entity. The model is entirely supportive of the view, and is concerned with supporting that view and nothing else.
For example, you show a list of your entities, what other data might you need? Current page number? Total number of pages? A custom message to be displayed?
This is why you should bind to a model, which you can freely add data items to as you need to.
Update
Here is an explanation of MVC in action...
The controller gets all of the data required for the request and puts it into the model. It then passes the model to the view.
The view then deals with the layout of the data in the model.
Each Model can be one entity that contains some methods to control and use its data.
Is it enough?
Hey guys - here's a question on Zend Framework or better on MVC in general:
I am asking myself for a quiet a long time now, if it is a good idea to push business objects (User, Team, etc.) to my views or if it would be better just to push dump data containers such as arrays to the view for rendering.
When pushing business objects to my view I have a much tighter coupling between the views and my domain model, however, the view could easily do things like foreach($this->team->getUsers() as $user) { ... } which I personally find very handy.
Providing domain model data in dumb arrays to me looks more robust and flexbile but with the costs of that the view cannot operate on real objects and therefore cannot access related data using object's method.
How do you guys handle that?
Thanks much,
Michael
It's better to make your View access a Domain Model object in an object-oriented manner, instead of using the Controller to convert Model data into plain scalars and arrays.
This helps to keep the Controller from growing too fat. See the Anemic Domain Model anti-pattern. The Controller only needs to know what Model to instantiate, passes the request inputs to that Model, and then injects the Model into the View script and renders. Keep in mind that a Domain Model is not a data-access class.
You can also write View Helpers to encapsulate a generic rendering of a Domain Model object, so you can re-use it in multiple View scripts.
Your View should accesses the Domain Model only in a read-only manner. View scripts should not try to effect changes to the Domain Model.
You can also design your Domain Model to implement ArrayObject or other SPL type(s), as needed to make OO usage easy in the View script.
It's true, a large driving motivation of MVC and OO design in general is decoupling. We want to allow each layer to remain unchanged as the other layer(s) are modified. Only through their public APIs do the layers interact.
The ViewModel is one solution to abstract the Model so that the View doesn't need to change. The one I tend to use is Domain Model, which abstracts the details of table design, etc. and supplies an API that is more focused on the business rather than the data access. So if your underlying tables change, the View doesn't have to know about it.
I would expect that if there's a change to the Domain Model, for instance it needs to supply a new type of attribute, then it's likely that your View is changing anyway, to show that new attribute in the UI.
Which technique you choose to decouple one layer from the others depends on what types of changes you expect to be most frequent, and whether these changes will be truly independent changes, or if they will require changes to multiple layers anyway.
The "standard" approach would be to completely prepare the model in the controller (e.g. fetch all teams, including users) and then send that to the View for presentation, but you are not bound by that. The data structures can be whatever you want it to be: Array, ArrayObject or custom Classes - anything you deem appropriate.
I dont use Zend framework, so this is in repsonse to the general MVC Have a look at the ViewModel pattern.
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx
I'm comming from a .Net MVC point of view but I believe the concepts will the same.
I will do all my view rendering in the controller bascially like below
model only output dataset/objects (this should contain the most code)
controller assign view and add necessary HTML and make use of models
view only contains placeholder and other presentation stuff and maybe ajax call
So my team can work on each part without interrupting each other, this also add some information security to the project i.e no one can retrieve all the working code they only communicate by variables/object spec.