MessagingCenter is a global event messaging system designed to allow two separate entities communicate without knowing anything about each other, besides a simple messaging contract. This architectural style of system works well for larger systems such as Amazon who use a similar event-sourced approach of micro services to implement a recommendation system, payment system, shipping system etc. These systems are distinctly separate and have teams working on each.
Mobile application development however is dealing with a much smaller system in most circumstances, with a single user interacting with a single page. To implement MessagingCenter in a mobile application is either a complete over architecture or its not being done properly.
Timing & State Issues
Timing issues are one of the largest concerns I have seen with MessagingCenter. If you load a page and OnAppearing is called and you have the possibility of a subscription to the MessagingCenter, how would you know if the OnAppearing got called first or the MessagingCenter. State validity is the main concern here as with all the following scenarios. MVVM is assumed in a few patterns.
ViewModel to Page
If you have a page binding to a ViewModel, the binding engine is there to relay information back and forth between the two entities. If you add MessagingCenter, then you add an additional path for the data to flow. If accessing a method on a control is the main concern, then expand the control to add Bindable Properties.
Page to Page
States should be managed by the Model, through the ViewModel, through the binding engine to the page. Jumping across pages can lead to immense state issues when your binding engine is competing with your subscriptions to modify page elements.
ViewModel to ViewModel
VM to VM communication is a common example of MessagingCenter usage. Communicating with an inactive VM boudn to a page that most likely isn’t showing yet is a pathway to timing and state issues.
To push data from one VM to another as you move pages in your application you can provide these mechanisms in your Navigation Service. The Navigation Service will already have a reference to your Page and ViewModel for binding and pushing purposes, why not just add a parameter to the Push command and pass that through when you have a reference to your new ViewModel.
// In your current ViewModel await _navigationService.Push(args); // In Navigation Service myPage.BindingContext = theViewModel; await _navigationPage.PushAsync(); theViewModel.OnNavigated(args);
Model to Model or Service
Models and services can talk to each other via constructor injection. If your model has a dependency on another model, then it should list it, as with services.
If you are now thinking that your Model’s have a hard dependency, this is true, but why shouldn’t they. It is obvious one depends upon the other, the MessagingCenter doesn’t alleviate the dependency, just makes it harder or you to track. You can go one step further and split the entity.
It is important that your models or services all implement an appropriate interface. With this approach you can restrict what a class does call of another and allow other classes greater API access.
Following Dependencies Not Events
Debugging code with events, especially ones tied together by magic strings, as is the case in most MessagingCenter implementations, becomes a nightmare. Following dependencies give greater assurance that operations are performed in sequence and that you can trace the code back without setting up debugging break points everywhere to trap an event.
While MessagingCenter isn’t suitable for many tasks, there is one where I have found use for it. This is with Background Processes. If you are downloading a file in the background, or performing some other intensive task, completely separate to the app, then MessagingCenter is a good way to transmit messages across two distinctly different operations. Other than this, I have found no other use for MessagingCenter.