Reactive Extensions with #uwpdev

Traditionally modern Windows application development (something done in the last 10 years) would involve using XAML. XAML is a great way to define a UI – it addition to it being declarative, it also supports Binding and Commanding.
MVVM – Model View View-Model has become the defacto pattern when developing XAML based applications… even a slow learner like myself eventually graduated to MVVM.

Anything that uses Binding needs to implement INotifyPropertyChanged interface by means on invoking PropertyChanged event to notify the UI of change.

MvvmLight toolkit which provides a large collection of helpful plumbing (RelayCommand, SimpleIoC, NavigationService and more) also provides an object called ObservableObject. This implements the INotifyPropertyChanged and devs just have to inherit from it and introduce their own properties ready for binding.
ReactiveUI a Reactive Extensions MVVM toolkit provides a similar class called ReactiveObject.

namespace ReactiveUI
{
    //
    // Summary:
    //     ReactiveObject is the base object for ViewModel classes, and it implements INotifyPropertyChanged.
    //     In addition, ReactiveObject provides Changing and Changed Observables to monitor
    //     object changes.
    [DataContract]
    public class ReactiveObject : IReactiveNotifyPropertyChanged, IHandleObservableErrors, IReactiveObject, INotifyPropertyChanged, INotifyPropertyChanging, IEnableLogger
    {
        protected ReactiveObject();

        //
        // Summary:
        //     Represents an Observable that fires *before* a property is about to be changed.
        [IgnoreDataMember]
        public IObservable Changing { get; }
        //
        // Summary:
        //     Represents an Observable that fires *after* a property has changed.
        [IgnoreDataMember]
        public IObservable Changed { get; }
        //
        [IgnoreDataMember]
        public IObservable ThrownExceptions { get; }

        public event PropertyChangingEventHandler PropertyChanging;
        public event PropertyChangedEventHandler PropertyChanged;

        //
        public bool AreChangeNotificationsEnabled();
        public IDisposable DelayChangeNotifications();
        //
        public IDisposable SuppressChangeNotifications();
    }
}

When creating observable objects, even ViewModel I tend to derive from ReactiveObject. Any derived class has access to tons of ReactiveExtensions.

For example, I mentioned that my work app Daily Mail Online is a SPA UWP app. I use a property called ViewMode to identify what View is loaded / shown to the user and what isn’t.

public ViewModes ViewMode
{
    get
    {
        return this.viewMode;
    }

    private set
    {
        this.RaiseAndSetIfChanged(ref this.viewMode, value);
    }
}

The method RaiseAndSetIfChanged is another extension method available to a reactive object. This raises PropertyChanged event if value has changed and UI needs to be informed. This would be great if ViewMode was bound to XAML but I wanted to observe any changes from different places. What I created was an observable using another extension method

public IObservable ViewModeObservable { get; private set; }
this.ViewModeObservable = this.WhenAnyValue(x => x.ViewMode)
    .Where(x => x != ViewModes.NotSet)
    .ObserveOn(CoreDispatcherScheduler.Current)
    .SubscribeOn(TaskPoolScheduler.Default);

I used an extension method called WhenAnyValue. It allows one to convert any property the raises PropertyChanged event as Observable.

Notice that I have set ObserveOn and SubscribeOn methods – those are not necessary here rather a subscriber can choose to set those. I set those here because I know this needs to be run on UI thread and any subscribers would need to do the same.
Now lets see how we can observe changes raised by this observable.

I hook into the ViewModel’s observable property in the View’s code behind. I am not an MVVM purist and I am happy to get into code behind if needed

this.MainViewModel.ViewModeObservable.Subscribe(async viewMode =>
{
    await _semaphoreViewMode.WaitAsync();

    try
    {
        switch (viewMode)
        {
            case ViewModes.Article:

                // do something
                break;

            case ViewModes.RelatedArticle:

                // do something
                break;

            case ViewModes.Channel:

                // do something
                break;

            case ViewModes.ReadLater:

                // do something
                break;

            case ViewModes.Comments:

                // do something
                break;

            case ViewModes.Search:

                // do something
                break;

            case ViewModes.Topic:

                // do something
                break;

            case ViewModes.Profile:

                // do something
                break;
        }
    }
    finally
    {
        _semaphoreViewMode.Release();
    }
});

The Subscribe extension method returns an instance of IDisposable. One can use that or use SerialDisposable to auto dispose previous subscription when a new subscription happens.

One can Subscribe to an Observable as many places as one needs.

Note: Its very likely that I am doing Reactive Extensions all wrong. Feel free to suggest better ways of using Rx

One thought on “Reactive Extensions with #uwpdev

  1. Pingback: Dew Drop - March 27, 2018 (#2692) - Morning Dew

Leave a comment