Reputation: 4598
I am trying to understand a piece of code in a legacy silverlight application.In this code as you can see user can publish an event and subscribe to that event.
while publishing event
Messenger.Publish<ErrorInformationData>(MessageConstant.ShowMessageTechnicalError,
new ErrorInformationData(ServiceOperationName.ClaimsService_GetClaim, ServiceOperationOccurence.DataServiceUI));
then subscribing to that event
Messenger.Subscribe<ErrorInformationData>(
this,
MessageConstant.ShowMessageTechnicalError,
(result) =>
{
Messenger.Publish(MessageConstant.ShowMessage,
new MessageData
{
Title = "Common$TechnicalError",
MessageText = "Common$TechnicalErrorDetail",
TextParameters = new object[] { result.OperationErrorCode.ToString() },
MessageType = MessageData.MessageTypes.OK,
OKAction = () =>
{
HtmlPage.Window.Navigate(new Uri("", UriKind.Relative));
},
MessageLevel = MessageData.MessageLevels.Error
}
);
}
);
Question is why do I need to use this framework where instead I can simply invoke a method.Also can anyone point to any documentation/tutorial regarding this communication.
Upvotes: 0
Views: 79
Reputation: 4598
Thanks @Nikosi for pointer, after more investigation I have found what's going on under the hood.
So there is a IMessanger
interface which contains signature of publish,subscribe and unsubscribe method.
public interface IMessanger : IDisposable
{
void Subscribe(IReceiver receiver, int messageId);
void Publish<TEventArgs>(object sender, TEventArgs e, int messageId)
where TEventArgs : EventArgs;
void Unsubscribe(IReceiver receiver, int messageId);
}
Now we define a class Messanger
which implements the interface.
public sealed class Messanger : IMessanger
{
private readonly Dictionary<int, List<IReceiver>> messageIdToReceiver;
public Messanger()
{
this.messageIdToReceiver = new Dictionary<int, List<IReceiver>>();
}
public void Subscribe(IReceiver receiver, int messageId)
{
List<IReceiver> receivers;
if (this.messageIdToReceiver.TryGetValue(messageId, out receivers))
{
receivers.Add(receiver);
}
else
{
this.messageIdToReceiver.Add(messageId, new List<IReceiver>() { receiver });
}
}
public void Publish<TEventArgs>(object sender, TEventArgs e, int messageId)
where TEventArgs : EventArgs
{
List<IReceiver> receivers;
if (this.messageIdToReceiver.TryGetValue(messageId, out receivers))
{
foreach (IReceiver receiver in receivers)
{
IReceiver<TEventArgs> receiverToReceive = receiver as IReceiver<TEventArgs>;
if (receiverToReceive != null)
{
receiverToReceive.Receive(sender, e, messageId);
}
}
}
}
public void Unsubscribe(IReceiver receiver, int messageId)
{
List<IReceiver> receivers;
if (this.messageIdToReceiver.TryGetValue(messageId, out receivers))
{
if (receivers.Count > 1)
{
receivers.Remove(receiver);
}
else if(receivers.Count == 1)
{
this.messageIdToReceiver.Remove(messageId);
}
}
}
public void Dispose()
{
this.messageIdToReceiver.Clear();
}
}
public interface IReceiver<TEventArgs> : IReceiver
where TEventArgs : EventArgs
{
void Receive(object sender, TEventArgs e, int messageId);
}
public interface IReceiver : IDisposable
{
}
Now we can see the usage of the above,Defined two classes one is publishing the event and other one is receiving the event.
public class PresenterA : IReceiver<EventArgs>, IDisposable
{
readonly IMessanger messanger;
public PresenterA(IMessanger messanger)
{
this.messanger = messanger;
this.messanger.Subscribe(this, (int)PubSubMsg.AppInstl);
}
public void Receive(object sender, EventArgs e, int messageId)
{
if ((PubSubMsg)messageId == PubSubMsg.AppInstl)
{
//Now that you received the message, update the UI, etc...
}
}
public void Dispose()
{
this.messanger.Unsubscribe(this, (int)PubSubMsg.AppInstl);
}
}
public class PresenterB
{
readonly IMessanger messanger;
public PresenterB(IMessanger messanger)
{
this.messanger = messanger;
}
public void btnApplicationRemove(object sender, EventArgs e)
{
//Do what you need to do and then publish the message
this.messanger.Publish<EventArgs>(this, e, (int)PubSubMsg.AppInstl);
}
}
public enum PubSubMsg
{
AppInstl = 1
}
Upvotes: 1