Midnight Thoughts about MVVM

What keeps bothering me about MVVM, is that user-defined views behave very differently from built-in controls. We use built-in controls like this:

<ListBox ItemsSource=... SelectedItem=... />

If, however, ListBox were our own user control, it probably have looked like this:

<ListBox DataContext="{Binding ListBoxViewModel}" />

class ListBoxViewModel
   public IEnumerable<bject> ItemsSource { get; set; }
   public object SelectedItem { get; set; }

This, of course, will make using ListBox much more complicated and cumbersome, as it would introduce a new entity called ListBoxViewModel, an instance of which must be created for each list box. Also, list box users would have to ensure that the view model supplied is indeed of type ListBoxViewModel, and not ListViewViewModel or TextBoxViewModel. The compiler would not check the type of the view model. If wrong view model is supplied, the list box would probably fail mysteriously at run-time, spewing a bunch of binding errors into the console window.

Thus, tying a view to a data context that must be of specific type inconveniences the users and makes the view difficult to reuse. If a view is responsible for displaying a business object, e.g. a Trade, from the view user’s perspective

<TradeView Trade={Binding aTrade} />

would be much more convenient, logical and safe than

<TradeView DataContext="{Binding aTradeViewModel}" />

However, if TradeView only receives a Trade object via property, it creates another problem. Let’s say TradeView needs to display some additional information about the security being traded, and this information is obtainable from ISecurityMaster service.

If TradeViewModel is passed to the view from the outside, it may contain ISecurityMaster reference, and obtaining that reference is not responsibility of the view. E.g., it may be done via some dependency injection framework, of which the view has no knowledge, and this is a good thing.

However, if the view only gets the Trade object, now it becomes the view’s responsibility to get the security master, and the view does not have enough context to do that. So, not only we will have to put some clever logic into the view, we will also need to use some kind of static (read: global) service locator, which will create hidden dependencies and affect testability of the application.

At this point I am not sure how to resolve this dilemma. Probably, by the time I come up with a satisfactory solution, everyone would be using WinRT anyway 🙂 Perfection is achieved at the point of collapse.

Leave a Reply

Your email address will not be published. Required fields are marked *