UI Patterns

Command Pattern

Here we will discuss different Command pattern approaches when developing UI user interactions through ICommand interface.

Sample application is provided in here: https://github.com/keozx/CleanRx/tree/master/src/samples/Commands

Also you can read the in deep post explaining each approach along with the demo App here: https://dev.to/keozdev/ui-command-pattern-268n

It is important to analyze each approach and the differences among them so when it is adopted within a team is easier to break barriers of adopting one framework or the other or small part of it. Most organizations will stick to one framework but that is seldom efficient when you need the best tool to get the job done. In my opinion, contrary to common belief, mixing up frameworks is actually a good thing, linking and proper dependency management should remove the clutter around having many tools in a single code base.

Command framework comparison

The intent here is to compare different Command frameworks out there, most of them of course are part of a bigger framework but breaking it up in small pieces helps in making the right choice on your current situation.

Feature XF Command DelegateCommand AsyncCommand ReactiveCommand
Executes a simple bindable Action ✔️ ✔️ ✔️ ✔️ <T>
Create from Task<T> (not async void) ✔️ ✔️
Retrieve unhandled exceptions ✔️ ✔️
Observes boolean changes for “CanExecute” behavior through INPC (not RaiseCanExecute) ✔️ ✔️ *WhenAnyValue
Observes IObservable ticks for “CanExecute” behavior ✔️
Guards against double execution (double tap) ✔️
Returns a <T> result at end of execution ✔️
Accessible “CanExecute” state ✔️
Accessible “IsExecuting” state ✔️
Subscribe to Completion and executes handler for <T> result ✔️

Xamarin.Forms Command

Based on above comparison, is there any reason to use XF Command? well only for a quick POC or if all you are really going to do is clicking a button and do something simple that does not require any other feature. However there may be some memory save if you are having a lot of simple buttons in a screen. A benchmark comparison coming soon. Xamarin Docs

Prism DelegateCommand

DelegateCommand is a better Command implementation because allows observing a boolean for ‘CanExecute’, but other than that, feels like a half-baked implementation of ICommand, not really intended in my opinion for use in complex apps. Prism Docs

AsyncAwaitBestPractices AsyncCommand

AsyncCommand comes from package Async Await Best Practices which apart from giving an implementation of ICommand with error handling, prevents the use of async void. Also the library provides for other good stuff like SafeFireAndForget() and WeakEventManager so is a handy package for Task based programming.

Unfortunately it does not provide CanExecute observer pattern like DelegateCommand, but is capable of catching exceptions if you provide an Error Handler parameter when creating the Command.

ReactiveUI ReactiveCommand

From all, from what you can see in the table ReactiveCommand is your swiss army knife implementation of ICommand, fully featured and rock solid, you can’t go wrong with it, the flexibility of IObservable as consumer and implementer gives us ultimate adaptability.

ReactiveCommand is also the only one capable of providing a generic typed result, additional to the default parameter in ICommand, to allow to retrieve the execution output, this is useful for Unit Testing because often you would want to assert the outcome of an operation starting with the click of a button end to end.

One thing that shines from the rest is also that it has built-in execution blocking so it won’t allow double tap or double execution if already fired, whether is a Task or an Action. Also, you can retrieve CanExecute and IsExecuting states to have better awareness for other components that may need to know execution state.

*While not directly capable of observing a boolean property, what RxUI Command offers is accepting the more robust IObservable type parameter for CanExecute behavior. You have to take an extra step to use WhenAnyValue() extension to wrap the INPC events from a property into an observable but in a real world application you rarely just watch for a single source, you could chain different observables here without having to notify of Can Execute has changed, so this is handy when having to watch multiple states at once and calculate whether or not the Command should be enabled or disabled.