Recently, I’ve been revisiting the concept of the CommandModel. I’ve posted about this before here and here. I’m a firm believer in using the Model-View-ViewModel in WPF, and I tried following along with the code presented by the folks who should be experts here. However, from the very beginning I had problems with the examples posted that used a CommandModel to represent the commands that would be carried out in response to UI events. I thought the troubles lied in the implementations. After all, they were simple examples and it was reasonable to assume they just didn’t live up to use in production with out appropriate tweaking. That’s what led to the previous posts I made on this subject. My final conclusion (prior to now) about this topic was that when implementing a CommandModel you should base it on ICommand instead of RoutedCommand. This solved the problems I had encountered thus far, and seemed like a good implementation.
Then it fell apart. See, RoutedCommand and RoutedUICommand offer you a lot of functionality you don’t get from ICommand. I knew that when I made the last post, of course, but the only feature I took into account at the time was the event routing, which I didn’t need. Well, there’s other features that are harder to do without. For instance, the simple fact that a RoutedUICommand has properties that can be used to set the text on a menu item is something that goes a long way towards keeping your XAML simple and clean. I could do with out this, of course, but it bothered my sensibilities. However, more important is the fact that you can add gestures, such as keyboard shortcuts, to a RoutedUICommand. That’s functionality I can’t do without. So the simple ICommand solution isn’t sufficient. Bummer. Back to the drawing board.
This time, however, I took a healthy pause to think about the concept from the design perspective, instead of from the implementation perspective. This proved to be enlightening, since I now think the whole concept of a CommandModel is flawed, and we shouldn’t be using them!
Just from a high level concept, they are flawed. What is a CommandModel? It’s a model of a command. So, what’s a model, then? A model defines data and behaviors for some given domain. There’s very little data involved here, there’s really only behavior. So I’m reluctant to call this a model at all. As far as the behavior is concerned… we already have plenty of concepts that can represent the behavior just fine, from delegates to Events to ICommands and it’s derivatives. What need do we really have to create yet another variant here?
OK, so with that in mind, let’s look at why the CommandModel was created. Of course, I can only guess here, since I didn’t create it and I’m not privy to the inside information about why the creators thought it was needed. So, let’s just analyze what we get out of a CommandModel.
Definition of behavior.
OK, as I already pointed out, we already have alternatives for this, so that can’t be the reason to have a CommandModel. Not to mention, as I pointed out before, the original designs for CommandModel did a poor job here, since they required a tight coupling to the ViewModel. I resolved that issue, but I think it’s evidence that this isn’t the reason the CommandModel was invented.
Wiring of UI events to behavior.
Well, since this was one of the major issues I had with the original examples, I don’t think this could be the reason. Or, at least, if it was the reason, I think the wrong solution was used. See, the CommandModel itself doesn’t help here. The examples used another concept, an attached property, to create the CommandBindings. This works, but it’s clumsy and verbose, and doesn’t really require a CommandModel to work. More importantly, there’s a better solution (which I’ll detail below). So, if this was the reason, then the wrong solution was chosen.
Allow testing without the need for a UI.
This is important. This is one of the main reasons that Model-View-ViewModel itself is such a useful pattern. However, all it really exposes to help us here are OnQueryEnabled and OnExecute methods that can be called. That’s it. When you think about that, it means it doesn’t really provide us with anything, because we can expose the event handlers within our ViewModel instead. Heck, with reflection we don’t even have to expose them. The event handlers are already testable, with out the need for a CommandModel.
No, I’ve come to the conclusion that the CommandModel is a flawed design, and I won’t be using it anymore. Instead, my ViewModels will expose the normal RoutedCommands. Then they’ll implement the necessary event handlers for ExecutedRoutedEventHandler and CanExecuteRoutedEventHandler, which can be unit tested. All that’s left is to create the CommandBindings, which can be done in the ViewModel’s constructor, thanks to the ViewModelExtension. This even makes it easy to create the CommandBindings for the standard commands provided by WPF, which is a very nice bonus.
So, if you’re following the Model-View-ViewModel pattern, take my advice and excise the concept of the CommandModel. You’re design will benefit from it. If your not following the Model-View-ViewModel pattern, take my advice and reconsider :).