Message buses allow us to decouple code
If you’ve used the MVVM pattern enough, you’ll sometimes find that you get “stuck” – you need to access a certain ViewModel (usually the “main” ViewModel), but at the point you need it, it’s too far removed from the context that you’re using it in. Sometimes if the object is a Singleton it’s appropriate to think of something like the Managed Extensibility Framework to get a reference.
Other times, a Messaging framework is more appropriate – ReactiveUI provides an “Rx”-take on the Messenger (Publish/Subscribe) pattern. With the Messenger pattern, we don’t have to make all our ViewModels related to each other, which is important for writing testable code, since I can easily replace related objects with mock objects.
ReactiveUI’s MessageBus is based on the Type of the message object. If the Message type isn’t unique enough, an extra Contract string can be provided to make the source unique.
There are three main methods that we’re interested in:
- RegisterMessageSource(IObservable source) – Register an IObservable as a message source – anything that is published on the IObservable gets published to the bus.
- SendMessage(message) – Publish a single item on the bus instead of having to use an Observable.
- IObservable Listen() – Get an Observable for the specified source – you can either Subscribe to it directly, or use any of the Rx operators to filter what you want.
Special support for singleton ViewModels
For ViewModels that only have a single instance, there are a number of helper methods that make using the MessageBus easier – use these methods instead of the above ones:
- RegisterViewModel(ViewModel) – Registers a ViewModel object; call this in your ViewModel constructor.
- IObservable ListenToViewModel – Listen for change notifications on a ViewModel object
- IObservable ViewModelForType – Return the ViewModel for the specified type