What are the responsibilities of a model in MVVM?

mvvm, wpf

Solution

Purpose of model is to model your domain. Entities, business logic, services - this all belongs to model. What binds it with UI is view model.

In your pump example, the `Pump` class should not implement `INotifyPropertyChanged` in order to utilize it in UI, because it should not be used in UI. That's the role of view model. More appropriate design would be

public class PumpService
{
   public void Start() { ... };
   public void Stop() { ... };
}

public class PumpControllerViewModel : INotifyPropertyChanged
{
    public PumpControllerViewModel(PumpService service)
    {
        StartPump = new Command(() => service.Start());
        // ...
    }
    public ICommand StartPump { get; private set; }
    public ICommand StopPump { get; private set; }
}

Model is in most cases almost invisible to UI. View model often exposes model properties, but seldom does so directly. If your application would require to display pump speed view model would have to expose it as observable property.

Update in response to OP question

(...) what if I had a more complex model with many properties, e.g. a Customer? (...) You suggest exposing each model property via an observable property on the VM - doesn't this involve a lot of duplication of properties, mapping code, etc?

Model complexity is irrelevant here and yes, such approach involes some code duplication (to some extent though).

If you keep your model simple (DTO/POCO-simple), then all you need to do is to rewrite POCO-model to INPC-view model. Model classes would have very little code while VM would handle to-the-view notifications (as to its role).

Assuming that most complex models are created via factory method/builder/service (as in, not directly), so could be the view models. And then you can utilize automappers, serializers or whatever that is you need to ease the duplication process.

You will have to maintain two similar classes but this is a worthy tradeoff for a clean separation MVVM offers.

Problem

I've always been a little confused as to what a "model" should or shouldn't contain - tutorials and examples often contradict each other. So far I've been playing it safe, with my models exposing nothing more than "UI stuff", e.g. properties for binding to the view, plus validation logic. But is it acceptable to have other business logic in a model? Let's say I want to control a mechanical pump via a web service, which provides methods to turn the pump on at a given speed, and to turn it off again. My UI view might include "on" & "off" buttons, plus a textbox to set the speed. With this in mind, my model might start out like this:- ``` public class Pump { public int Speed { get; set; } } // The real thing would implement INotifyPropertyChanged, validation, etc. ``` Is this all the model should be doing, or is it acceptable to expose the business logic for turning the pump on and off - either as methods for the view-model to call, or maybe even as ICommands that can be bound directly to the view's buttons? Or should all this be in the view-model? Edit Not sure why the downvotes, as I think this was a perfectly reasonable question. While there are many MVVM tutorials and examples on the web, they often provide conflicting advice as to what goes where, much like the answers provided below. I even ended up reading the "Advanced MVVM" e-book by WPF expert Josh Smith - the book didn't mention models whatsoever! Anyway, I found a good resource here for anyone who wants to undersatnd the structure of MVVM. While the link takes you into documentation for Microsoft's Prism framework, this particular page is all about MVVM structure, with little or no Prism-specifics. I found the page to be very informative and has at least put my mind at ease, confirming that what I've been doing over the last couple of years to be perfectly valid - that is, having models that implement INPC and validation (IDataErrorInfo), and binding these models directly to the view via VM properties (rather than duplicate model properties in the VM, as some answers below advocate).

Original source