In talking to developers around Windows/Phone applications I often find that there’s something of a “tax” in being able to get to the position of discussing a simple example that uses views, models, viewmodels, services and I kind of wish that the Visual Studio templates and XAML frameworks provided more in this area in order to avoid developers having to decide;
- Do I need this MVVM thing?
- How far do I go with it?
- Is it something that Microsoft “wants” me to do or am I going against the flow?
- Should I invent something to fill the gaps that I seem to encounter?
- Which of the existing MVVM libraries/frameworks should I use if I don’t invent?
I was thinking about this in writing my previous blog post and thought I’d jot down some quick examples of where it feels like I’m paying that “tax” in building up examples;
1. Where’s My Implementation of INotifyPropertyChanged?
I’m a bit stunned that the .NET framework provides INotifyPropertyChanged but no base class to implement it for a developer. Given that data-binding is so powerful and common in XAML-based applications and that data-binding really relies on on “INPC” ( hey, it’s even so common that we’ve abbreviated it over the years to “INPC” ) I’m surprised that the framework doesn’t ship with some implementation.
2. Where’s My Implementation of ICommand?
Pretty much the same thing. Given that most folks agree that you want to separate out your View from its ViewModel and given that binding is a great way of doing it and given that ICommand is provided in the framework and is pretty much the means via which we can bind a View to executable behaviour, why not give the developer an implementation of it in the platform then we all can use the same one and agree on what it does?
3. Can Navigation be Separated from the Frame?
I’d really like to see the idea of navigating around the app to be separated from having access to a Frame object. I might want to write some piece of code somewhere deep in a library that causes navigation to (e.g.) a “details page”. I’d like that code to be able to make a call like NavigationService.Navigate(“details page”). I don’t really want that piece of code to have to know about the UI in the sense of having access to a Frame object. I’d prefer to see some abstracted NavigationService that a Frame can hook into rather than tying the two things together.
4. Can Navigation be Separated from the Type of the View?
While thinking about navigation, I’d really like a navigation service to deal with some simple token like “details page” rather than some concrete type. Maybe some convention can be applied such that “DetailsPage” would be default resolve to some type called DetailsPageView or similar so long as that convention can be overridden.
5. Can a Service be Provided to Wire up the View to its ViewModel?
Where a view (whether a UserControl or a Page or whatever) today has a DataContext I’d like it to have some kind of “DataToken” or “ViewModelName/Token” property. That token could be something as simple as a string that, again, convention can be applied to in order to resolve a view model to go with a view. That is, a page could specify Page.ViewModelName=”Foo” and the XAML framework could apply an overridable convention for how the string “Foo” gets resolved into an instance of a view model.
6. Can ViewModels Understand Navigation?
If we want to cleanly separate a View from its ViewModel then it’d be great for the ViewModel to have an “awareness” of when things are happening in the app. For instance, a ViewModel might want to “know” when it is being created for the first time and it might want to “know” when it is being discarded and/or re-used.
The challenge with the bits as they ship with Visual Studio is that it is the ViewModel that has the data but the View (i.e. Page) that the awareness of whether it is being navigated from/to and whether that navigation involves being created for the first time or is a re-use from cache and so on. The developer’s then left to try and figure out how to get that information from the View to the ViewModel.
7. Can There be a Slot for an IoC Container?
This is somewhat a corollary of items 4 and item 5 above. Typically, I have a View which has some ViewModel behind it which has some dependency on some Services living below it. I’d like the framework to allow for resolving these types via an IoC container (of any type). Now, if I have item 4 and item 5 above then I can probably build that myself but I’d like to see the framework make it much easier for developers to just assume IoC rather than treat it as some oddity.
8. Can ViewModels Understand Suspend/Terminate?
Similar to point 6 above – in the XAML frameworks for Windows/Phone 8.1 apps today there’s little automatic support for saving/restoring state when an application needs to suspend/terminate and then re-run and get the user back to where they were when the app was terminated by the OS. There’s a class in the app templates called SuspensionManager which links up with some other classes (Frame, Page, NavigationHelper) to ensure that your Page navigation history (+ parameters) can be saved but this largely operates at the Page (View) level rather than offering support to the developer who needs that at the ViewModel level.
Those are the first 8 that I thought of. I’m sure there are more.
Now, of course, I can build these myself. More likely, I can go and use someone else’s implementation – e.g. a framework like MvvmLight or Prism or MvvmCross or one of those would probably cover all of these and much more (e.g. loosely coupled events might be another thing that I’d want).
The “problem” is that if those frameworks don’t ship plugged in as a default for Visual Studio then at least three things happen;
- A developer is faced with those immediate choices of “which of these is the right one to go with if I need any of them?”
- A conversation always has to be brokered around “do you use X, Y or Z?” with a fallback conversation if a developer doesn’t.
- The tooling can’t make an assumption that a developer will be working with framework X in a particular pattern and then start to help that developer by building higher levels of abstractions on top of that assumption.
I thought I’d jot these down. It’s not an attempt to complain or to rant but a suggestion as to something that I think could improve developing these kinds of apps and, as always, I’m keeping my eye out for anything that comes along and adds in these areas. Feel free to discuss in comments below and especially if you think it’s something that you wouldn’t want to see change – always looking for contrary viewpoints!