I know there are already questions on that topic, but the issues there are somewhat specific to other problems and do not offer conclusive answers.
Especially those here: Question1, Question2 and of course Question3 so please do not close this question too fast. They answer there just say "Do this, do that" and not why!
There are people out there that deny the need for a ViewModel
and say that
the "standard" way is to bind to the Model directly. This is what I deny and try to prove with technical arguments.
From my background in MVC
, MVP
, Presentation Model
, it just is natural
to me to use a ViewModel
. Perhaps I miss an important point?
So for me the default is to bind to a ViewModel
, no matter what the Model
is (and no matter if it implements INotifyPropertyChanged
or not).
There are several reasons that I see for binding to ViewModel
s, including
(As mentioned here CodeProject and here on another article)
1. Removing logic from the View
- Make logic unit testable
- reduce code redundance (duplication where needed)
2. Security
- The model contains properties that the user shall not change
- Automatic, but unwanted updates can happen if Binding to model
3. Loose coupling
- If binding directly to the model, there will be a coupling between lower layers and View
- Changing the Model causes changes in all the Views
- The view is not depending on any given model
- Model can be easily generated with EF, some DSL, batch files, on so on
4. Speed of development
- You can start with a
Prototype ViewModel
hierarchy and bind to that - If the model is still under development, you can start with a
Prototype Model
Model
andViewModel
can be developed testdriven, no matter of the View- The
View
can entirely be built by a designer, or developer with strong design background
5. "Tricky synchronizion" is solved
- There are plenty of solutions to any given "tricky synchronization" problem, e.g.
- AutoMapper
- Event system from the model (model fires event, ViewModel subscribes)
6. Equal structure throughout the project
- There are points where have to a ViewModel, like SelectedItem
- Mixing Binding to Model and ViewModel is errorprone
- It is harder for fresh developers to figure out structure of the project
- starting to bring ViewModel later when there is no way around it is messy
7. Scalability
- Lets define: If you do not use a ViewModel, it is not MVVM
- MVVM can be easily adopted to lots of datasources, lots of views
- If you find any performance issues: Lazy loading and caching goes in the ViewModel
8. Separation of concerns
- Getting a grip on complexity is the main problem in software
- The ViewModels sole responsibility is pushing changes
- It is as easy to send notifications to a view as it is to push it to a different process or machine
- The ViewModel, not the View register for change notifications on the model / data source
- the datasource can ignore sending events to the ViewModel that caused the change
On contrary, the guy from the other thread dumps some points, including
If the model is updated directly, the view-model won't know to fire a property changed event. This causes the UI to go out of sync. This severely limits your options for sending messages between parent and child view-models.
If the model has its own property changed notification, #1 and 2 aren't a problem. Instead, you have to worry about memory leaks if the wrapper VM goes out of scope but the model doesn't.
If your models are complex, with lots of children objects, then you have to walk the entire tree and create a second object graph that shadows the first one. This can be quite tedious and error prone.
Wrapped collections are particularly difficult to work with. Any time something (UI or backend) inserts or removes an item from a collection, the shadow collection needs to be updated to match. This kind of code is really hard to get right.
So, the question is: what is the default way to bind and why?
Do I miss points that make it necessary to have a ViewModel?
Are there any real reasons one would like to bind to a model?
Most important is the why, not the how to.