I have been using MVVM for a few years now and always felt it needed a summary of the state of things as well as my own opinion about it. This is it today. My approach to MVVM has been changing from the time when I was an eager student, through a devoted disciple, till today when I see it as a small tool in the toolbox of a XAML developer.
The original article has been republished by Safari Books Online.
The Model View View Model (MVVM) pattern is an architectural pattern used for separation of concerns in applications. It is popular in Microsoft’s XAML-based UI frameworks such as WPF, Silverlight or WinRT/XAML.
The MVVM architecture consists of the View layer (the UI design implementation), the View Model layer that provides bindable properties and commands to the view and the Model layer that contains the application’s actual domain model and business logic. The connection between these layers is such that the view model knows nothing about the view (it does not reference it) and the model knows nothing about either of the other two layers.
The qualities of an application architected based on the MVVM pattern are
- Maintainability – separation of concerns and loose coupling helps modify one layer without affecting the other layers
- Testability – being able to replace the view as well as view model with a test fixture allows to test the layers separately and avoid having to use unreliable and hard to maintain UI automation for all tests. That also helps overall maintainability of the code, since a change can be made in one part of code while tests reduce the risk of regressions in other areas.
- Blendability – view models can fairly easily be replaced with design-time data and logic, so designers can create the views using Blend independently of other development work.
- Ability to split work among multiple developers – not only the views can be implemented by designers or integrators, but also view models can be created separately from the models by mocking the models.
- Portability – the view models and models can theoretically be reused in versions of the same app for different platforms.
MVVM was made possible in WPF – the original XAML framework thanks to the XAML layer that is the declarative description of the view as well as bindings – that allow to declaratively specify which properties of the view model are displayed or manipulated by the view, and commands that allow to represent actions executed by the view model in form of bindable properties. However, anyone trying MVVM for the first time soon notices problems with MVVM, such as
- What are commands and why should I use them?
- What gets created first – the view or the view model and how to connect the two?
- Animations – how to trigger an animation from the view model or do something when an animation completes?
- Navigation and dialogs – where to initiate navigation and dialogs – from the views or the view models?
- State persistence – while saving the state of the application was a nice feature in the past – it is virtually required on modern platforms such as Windows Phone or Windows 8 – how to store and restore the state of the view and the view model though?
- Non-bindable properties – a lot of the properties in the UI frameworks are not bindable, such as grid column and row definitions, Windows Phone application bar or in many cases – the style setter values.
- Bindable properties are rather verbose – instead of using auto properties – even for the most basic bindable properties you need to invoke property change notification events.
The languages and the UI frameworks lack built-in solutions to these problems, so the developer community has responded with many frameworks that try to address these issues. Some of the more known libraries maintained by known experts in the XAML community are
- MVVM Light Toolkit (by Laurent Bugnion) – most popular possibly because it really is pretty lightweight with just the basics of MVVM covered and the source code is easy to understand. For all platforms.
- Caliburn.Micro (by Rob Eisenberg) – a bit more complicated, but supports convention-based approach where bindings are not explicitly specified and XAML is kept eerily clean. For all platforms.
- Prism (by Microsoft patterns & practices team) – official guidance from Microsoft for developing composite applications with WPF, Silverlight and Windows Phone.
- WPF Application Framework (WAF) – a popular, WPF specific library
- ReactiveUI (by Paul Betts) – based on Reactive Extensions – a bit exotic part of the .NET framework that is well suited for highly asynchronous applications. For all platforms.
- Cinch (by Sacha Barber) – a “Rich Full Featured WPF/SL MVVM Framework”.
- nRoute (by Rishi Oberoi) – a big library with a lot of features, available for all XAML platforms.
- Catel (by Geert van Horrik) – another rich framework with MVVM support with support for all platforms.
- MVVM Foundation (by Josh Smith) – one of the early MVVM frameworks for WPF by an early MVVM advocate. Worth checking due to its small size and simple project structure.
- Jounce (by Jeremy Likness) – “Silverlight MVVM + MEF Framework”.
- Calcium (by Daniel Vaughan) – composite application toolset for WPF/Windows Phone.
Over the years MVVM Light, Caliburn.Micro and Prism have grown to be the three most popular frameworks with the biggest communities around them and are the best choices to start with, though the other libraries have interesting features that are worth checking too.
MVVM for WinRT
Should you use the BindableBase class and is it enough to build MVVM-based applications?
I still do recommend using MVVM Light Toolkit or Caliburn.Micro for larger projects, since they provide features that you will most likely need sooner or later as your application grows and if you want to keep it implemented in clean MVVM fashion, however over the years as these libraries have grown in popularity, they have also grown in features and the built-in cross-platform support, made them more complicated and harder to study. Sure – with NuGet you can now have the latest version of MVVM Light referenced by your project within a few clicks, but then you cannot see the source code and it is harder to figure out how it works or how to use it, especially with the growing number of APIs available.
For smaller projects – the BindableBase from the Visual Studio templates might just be enough. Though a snippet for observable properties as the “pp” snippet in my snippets helps a lot (just install the snippets and type pp[TAB] to insert an observable property in your view model). Commands? Do you really need them to implement the MVVM pattern? A regular public method on the view model works just as well and if you need to disable or enable a button based on whether a method can be executed – a regular observable property like “CanExecuteMyMethod” works just as well as a CanExecute method of a command. By the way – if you really want to – you can still create any MyCommand class that implements an ICommand interface – it is not that much more code than using a DelegateCommand/RelayCommand of Prism/MVVM Light, though admittedly these do make it a lot easier to inline its implementation.
Not using a third party MVVM helper library has many benefits – no need to install anything, no dependencies, no reliance on reflection, no dead code in form of unused framework APIs, no need to justify using open source code at companies that do not generally allow it. It is just what you get with the standard templates.
Of course these existing libraries have custom solutions to some specific problems and provide generic solutions to others, but usually eventually you stumble upon something that the library you chose just does not solve. In such cases I sometimes build my own reusable libraries or controls or just write some one-off piece of code that glues MVVM together. If the problem you need solved involves some custom interaction logic – you are going to be better off implementing a custom control or attached behavior than trying to stuff everything in the view model.
Ultimately using code behind is an easiest choice and does not invalidate MVVM. Experts in the field such as Laurent Bugnion have long been saying that MVVM is just a pattern and you should not be afraid of using code behind in your applications. However religiously it seems to be treated by many developers – if you just start by using view models to drive your views – it is enough to reap most of the benefits of the pattern and will help you create a maintainable application. Unless you are building a big line of business application, planning on unit testing your complicated view model logic or doing a lot of UI development using Blend – you might not need a fully separated view and view model. If you are working on a big project though, or your project just grows big – you might consider one of the popular frameworks or building your own. At some point you will just find that you can’t live without a pub-sub implementation like MVVM Light’s Messenger or Prism’s EventAggregator, you will want to write unit tests and find a need for an IoC container, so you can mock and shuffle your components., you will want to bind everything even if Microsoft’s does not support the binding you want. Until then though – feel free to start small and lean and worry about features rather than patterns. MVVM is just one of the tools to build an app and you might find that learning about custom layout logic, touch interaction, custom controls or behaviors is going to benefit you more than wondering which MVVM framework to use.