Silverlight MVCVM – MVVM With Controllers

First a little background on MVVM…

MVVM (Model, View, ViewModel) is a pattern for separating logic from Silverlight XAML pages (the UI).

  • A View is simply a UI page. It does not know where the data is coming from.
  • A ViewModel holds a certain shape of data, and commands, that a View binds to.
  • The model refers to the actual business data, which is used to populate the ViewModels.

The main benefit is that a XAML/UI designer can edit the look and feel of UI pages while a Silverlight developer makes them work, without them constantly tripping  over each other. This is a good thing.

The problem we see with MVVM…

The problem with MVVM, as it stands, is that we see lots of people trying to cram their business logic into the ViewModel. Having so much app logic, in what is basically a storage box, does not make unit testing easy. In fact it makes it a lot more difficult. This feels like a bad fit. In code-speak, the pattern just “smells wrong”.

Then a light went on…

While trialing an application generation package, called Sculpture, we noticed it generated code for a number of platforms and in all cases it kept the application logic in separate controller classes. That included its MVVM style code for Silverlight and WPF. This seemed like an interesting idea, so we investigated further and applied the idea to a few of our own projects. The results not only felt good but that bad-code smell evaporated :)

The basic MVCVM mantra:

  • ViewModels are just dumb containers that hold a certain shape of data: “They do not know where the data comes from or where it is displayed”.
  • Views display a certain shape of data (via bindings to a view model): “They do not know where the data comes from, only how to display it”.
  • Models supply real data: They do not know where it is consumed”.
  • Controllers implement application logic. “The listen and broadcast messages/events”.

Controller supply the code for ICommands in VMs, listening for changes to data etc.

Controllers populate VMs from Models.

Controllers listen for VM changes and update the Model.

Basically Controllers become the glue that hold complete independent components together and turn building blocks into applications.

“Long live controllers!” – This series will be updated with examples soon…

7 Comments

  • By Raziaar, August 12, 2012 @ 8:13 am

    I’m excited to read about what you have to say on this subject. I’m still trying to learn what I can since so many of these concepts are new to me and I’m trying to learn them all at once.

    The main question I have right now… is how do the controllers go about populating all the properties of the ViewModels? I can’t figure out if it’s something that should be dependency injected, or if the controller simply goes through and sets all the properties(making sure to get every last one) to initialize it and later in methods as events are triggered.

    I’m kind of at a hang up right here as I try to figure out how the viewmodel gets everything it needs from the controller, since you say the viewmodel is just a dumb container of data for the view.

    Examples will definitely be helpful.

  • By admin, August 12, 2012 @ 9:50 am

    Good questions. MVVM has everyone populating data from inside their ViewModel, making them smarter than they should be (the VMs, not the people). Controllers will populate ViewModels from the data sources instead (usually in response to app events/messages).

    Basically whatever code you would have in your viewmodel at the moment, to populate data members, migrates directly to a controller. If you have an EF model in your VM, then your controller will have an EF instance (or create one when needed) and move the query results to a VM property. If you use service calls to populate data, then those service calls will now happen in the controller.

    It is possible to bind DataSources to a VM as well, so you can also make a lot of drag-drop data stuff you author in XAML more flexible and not bound to a single source. All binding and datasource related operations use reflection to connect/move data so only the shape of the data (i.e. the property names) are actually important. That’s why I say “a VM provides a certain shape of data”.

    The main thing to remember with MVCVM is that the individual building blocks should appear completely independant and only responsible for things they should know about. This makes them easily unit testable. The only cross-dependant parts in an MVCVM app are the controllers. Controllers do need to know about their Views, their View Models and their Data Sources/Models. Controllers are the glue that connects your otherwise independant components into an overall app. They are the app logic. Everything else is just there to serve them :)

    I will be updating this series with examples, specifically a large multi-module Prism app, over time.

  • By Raziaar, August 12, 2012 @ 7:24 pm

    Thank you for the response. Unfortunately I do not seem to be following along completely, and for that I apologize.

    If your ViewModel has ICommand properties set for various commands such as ProductAddedCommand, are you simply defining the methods in your Controller and assigning them after instantiating the ViewModel?

    viewModel.ProductAddedCommand = new DelegateCommand(AddProduct, CanAddProduct);

    Or are you taking a different approach?

  • By admin, August 12, 2012 @ 7:39 pm

    It will take a few examples I think to clarify things, but your example is correct:

    The VM ICommand properties are again only a named placeholder for a View to bind to. Any given controller could reuse the same VM in different ways, by assigning different ICommand code/delegates.

  • By Raziaar, August 18, 2012 @ 9:01 pm

    I know that a ViewModel should know nothing about the model it’s exposing for the View. How should a ViewModel represent a Person object in the Model. Does the ViewModel define it’s own class, and the Controller do a conversion between the Person on the Controller, and the Person on the ViewModel?

    How does all that work? What’s the ideal way you prefer?

  • By Raziaar, September 4, 2012 @ 2:33 am

    So I’m well on my way with this… at least I’d like to think so. Part of me thinks I’m doing everything wrong. But oh well.

    A problem I’m facing right now is dealing with the CanExecute of an ICommand to enable or disable buttons in my view. I can’t figure out how to accomplish this in the Controller.

  • By Raziaar, September 4, 2012 @ 3:12 am

    Well this is how I ended up doing it… doubt it’s the proper way, but it works.

    viewModel.HostChat = new DelegateCommand(ExecuteHostChat, CanHostChat);
    viewModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(ViewModelPropertyChanged);
    }

    void ViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
    if (e.PropertyName == “Name” || e.PropertyName == “Port” || e.PropertyName == “Address”)
    {
    (viewModel.HostChat as DelegateCommand).RaiseCanExecuteChanged();
    }
    }

    public bool CanHostChat()
    {
    if (String.IsNullOrEmpty(viewModel.Address) ||
    String.IsNullOrEmpty(viewModel.Port) ||
    String.IsNullOrEmpty(viewModel.Name))
    {
    return false;
    }
    else
    return true;

    }

Other Links to this Post

RSS feed for comments on this post. TrackBack URI

Leave a comment

You must be logged in to post a comment.

WordPress Themes