Tuesday, July 26, 2016

Thoughts on making TinyPubSub a little less tiny

Thoughts on making TinyPubSub a little less tiny

TinyPubSub is a very simple Publish/Subscribe library created mainly for passing events between views in an Xamarin Forms application that uses MVVM. You can read about it at https://github.com/johankson/tinypubsub.
What I'm thinking about doing is extending it with two features
  • Passing of data
  • A stack based recipient model

Passing of data

TinyPubSub only allows for publishing events from one source to many recipients. It was originally create for notifying other views to reload or refresh their data. At first this was pretty much all it was intended to do. But now I can't help myself and I would really like to publish data as well.
This is the original way to subscribe and publish an event.
In the first view model
   () => { RebindGui(); });
In another view model
Let's say I want to pass data, it could look like this
   (c) => { RecolorDuck( c ) } );
And in the publish part
TinyPubSub.Publish("duck-color-updated", c);

An example

Let's say you're buildning an app for configuring a car. The first page is to choose the model. On this page there is a button to choose your color. The original page simply registers for the color-chosen event and waits happily for that to happen. We then create a generic choose color page that knows nothing about what page that really needs that color. When the color finally is choosen the page fires a color-chosen event and the first page will receive it.
All is fine until you get another subpage that also wants a color choosen. You can solve that in a number of ways. The first being to register different events for different colors choosers and pass an argument to when we create the color picker page. This is messy and could easily get out of hand.
My proposed solution is to create a function where you can state that only the latest registered listener will handle the event.

A stack based recipient model

Enter the stack based recipient model.
The mechanism behind this is simple. The latest registered recipients of a specific event is the only one that will receive an event.
Since all events for a page is deregistered automatically in TinyPubSub it will be simple to reuse the color-picker page multiple times.
To revisit the car example, just before clicking the button for coloring your car door you register to the color-chosen event with the `SubscribeExclusive(...) method.
   (c) => { RecolorCarDoor( c ) } );
await Navigation.PushAsync(Resolver.Resolve());
Then it doesn't matter if you have another page listening for the color-chosen event. Only the page before will get the event. And when the page goes out of scope, the subscription for the event will be removed and the page before will get the event instead.
This also means that the ColorPickerPage could check at runtime to see if there are any recipients at all and throw an Exception if there is none.


This is still not implemented. I thought I just write it down first and get some comments on it.