2017-08-04 11 views
0

J'essaie de comprendre un morceau de code dans une application Silverlight legacy.Dans ce code que vous pouvez voir l'utilisateur peut publier un événement et vous abonner à cet événement.Publier et s'abonner à des événements dans silverlight

tout événement d'édition

Messenger.Publish<ErrorInformationData>(MessageConstant.ShowMessageTechnicalError, 
new ErrorInformationData(ServiceOperationName.ClaimsService_GetClaim, ServiceOperationOccurence.DataServiceUI)); 

alors inscrivez-vous à cet événement

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 
             } 
            ); 
           } 
           ); 

La question est pourquoi dois-je utiliser ce cadre où la place que je peux simplement invoquer un method.Also quelqu'un peut-il le point de toute documentation/tutoriel concernant cette communication.

+0

Difficile à dire à partir de ce morceau de code. Une bibliothèque MVVM peut être en cours d'utilisation. Cela peut expliquer ce type de messagerie car c'est un moyen connu de communiquer des commandes, etc. Jetez un oeil à la section des références du projet. Cela pourrait nous éclairer sur les dépendances externes utilisées. –

+0

Le code semble implémenter le motif médiateur. Utilisé pour découpler la communication entre les modèles. – Nkosi

Répondre

0

Merci @Nikosi pour le pointeur, après plus d'enquête, j'ai trouvé ce qui se passe sous le capot. Il y a donc une interface IMessanger qui contient la signature des méthodes publish, subscribe et unsubscribe.

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); 
} 

Maintenant, nous définissons une classe Messanger qui implémente l'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 
    { 

    } 

Maintenant, nous pouvons voir l'utilisation de ce qui précède, définit deux classes qu'on publie l'événement et l'autre est réception de l'événement.

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 
    }