Xamarin.Forms provides cross-platform messaging capabilities for Android, iOS and Windows Phone with its MessagingCenter – but in a really strange fashion. I thought there must be a simpler way.
Published on Mon, January 18, 2016
Working with the MvvmCross Messenger Plugin for a while now, I got used to the idea of just sending simple message objects that I can define myself.
All you need to do with that MvvmCross messenger is to create a new message type, derive it from MvxMessage and publish it.
The interface for sending is that simple. And even subscribing to messages of a certain types is that simple as well – you define the type of the message you want to listen to, a callback which gets a parameter of that message type, and you're basically done. Read more about it here.
If you're now taking a look at the MessagingCenter of Xamarin.Forms, some things appear to be a bit odd:
I thought especially independence of sender and subscriber should be a goal worth doing some extra work. And here it is:
public interface IMessage
{
}
public interface IMessenger
{
void Send<TMessage>(TMessage message, object sender = null)
where TMessage : IMessage;
void Subscribe<TMessage>(object subscriber, Action<object, TMessage> callback)
where TMessage : IMessage;
void Unsubscribe<TMessage>(object subscriber)
where TMessage : IMessage;
}
public class FormsMessenger : IMessenger
{
public void Send<TMessage>(TMessage message, object sender = null) where TMessage : IMessage
{
if (sender == null)
sender = new object();
MessagingCenter.Send<object, TMessage>(sender, typeof(TMessage).FullName, message);
}
public void Subscribe<TMessage>(object subscriber, Action<object, TMessage> callback) where TMessage : IMessage
{
MessagingCenter.Subscribe<object, TMessage>(subscriber, typeof(TMessage).FullName, callback, null);
}
public void Unsubscribe<TMessage>(object subscriber) where TMessage : IMessage
{
MessagingCenter.Unsubscribe<object, TMessage>(subscriber, typeof(TMessage).FullName);
}
}
Usage now is very straight-forward.
public class AlbumCreatedMessage : IMessage
{
public readonly Album Album;
public AlbumCreatedMessage(Album album)
{
Album = album;
}
}
var album = new Album
{
Id = Guid.NewGuid(),
Title = "Hello World"
};
// An instance of IMessenger
Messenger.Send(new AlbumCreatedMessage(album));
// An instance of IMessenger
Messenger.Subscribe<AlbumCreatedMessage>(this, AlbumAdded);
private void AlbumAdded(object sender, AlbumCreatedMessage message)
{
// Do something
}
Messenger.Unsubscribe<AlbumCreatedMessage>(this);
I think that's a clean way to send and receive messages.