从Prism中学习设计模式之Event Aggregator 模式

Event Aggregator 模式定义:渠道事件从多个对象通过一个单一的对象来简化clients的注册。

结构图:

Prism的Event Aggregator 模式:Event Aggregator允许多对象定位和发布、订阅事件。

我们从Prism源代码中的EventAggregator和CompositePresentationEvent可以学习它是如何管理和传递事件消息的。

  1     public interface IEventAggregator
  2     {
  3         TEventType GetEvent<TEventType>() where TEventType : EventBase, new();
  4     }
  5 
  6     public class EventAggregator : IEventAggregator
  7     {
  8         private readonly Dictionary<Type, EventBase> events = new Dictionary<Type, EventBase>();
  9 
 10         public TEventType GetEvent<TEventType>() where TEventType : EventBase, new()
 11         {
 12             EventBase existingEvent = null;
 13 
 14             if (!this.events.TryGetValue(typeof(TEventType), out existingEvent))
 15             {
 16                 TEventType newEvent = new TEventType();
 17                 this.events[typeof(TEventType)] = newEvent;
 18 
 19                 return newEvent;
 20             }
 21             else
 22             {
 23                 return (TEventType)existingEvent;
 24             }
 25         }
 26     }
 27 
 28   public class CompositePresentationEvent<TPayload> : EventBase
 29     {
 30         private IDispatcherFacade uiDispatcher;
 31 
 32         private IDispatcherFacade UIDispatcher
 33         {
 34             get
 35             {
 36                 if (uiDispatcher == null)
 37                 {
 38                     this.uiDispatcher = new DefaultDispatcher();
 39                 }
 40 
 41                 return uiDispatcher;
 42             }
 43         }
 44 
 45         public SubscriptionToken Subscribe(Action<TPayload> action)
 46         {
 47             return Subscribe(action, ThreadOption.PublisherThread);
 48         }
 49 
 50         public SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption)
 51         {
 52             return Subscribe(action, threadOption, false);
 53         }
 54 
 55         public SubscriptionToken Subscribe(Action<TPayload> action, bool keepSubscriberReferenceAlive)
 56         {
 57             return Subscribe(action, ThreadOption.PublisherThread, keepSubscriberReferenceAlive);
 58         }
 59 
 60         public SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive)
 61         {
 62             return Subscribe(action, threadOption, keepSubscriberReferenceAlive, null);
 63         }
 64 
 65         public virtual SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate<TPayload> filter)
 66         {
 67             IDelegateReference actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);
 68             IDelegateReference filterReference;
 69             if (filter != null)
 70             {
 71                 filterReference = new DelegateReference(filter, keepSubscriberReferenceAlive);
 72             }
 73             else
 74             {
 75                 filterReference = new DelegateReference(new Predicate<TPayload>(delegate { return true; }), true);
 76             }
 77             EventSubscription<TPayload> subscription;
 78             switch (threadOption)
 79             {
 80                 case ThreadOption.PublisherThread:
 81                     subscription = new EventSubscription<TPayload>(actionReference, filterReference);
 82                     break;
 83                 case ThreadOption.BackgroundThread:
 84                     subscription = new BackgroundEventSubscription<TPayload>(actionReference, filterReference);
 85                     break;
 86                 case ThreadOption.UIThread:
 87                     subscription = new DispatcherEventSubscription<TPayload>(actionReference, filterReference, UIDispatcher);
 88                     break;
 89                 default:
 90                     subscription = new EventSubscription<TPayload>(actionReference, filterReference);
 91                     break;
 92             }
 93 
 94 
 95             return base.InternalSubscribe(subscription);
 96         }
 97 
 98         public virtual void Publish(TPayload payload)
 99         {
100             base.InternalPublish(payload);
101         }
102 
103         public virtual void Unsubscribe(Action<TPayload> subscriber)
104         {
105             lock (Subscriptions)
106             {
107                 IEventSubscription eventSubscription = Subscriptions.Cast<EventSubscription<TPayload>>().FirstOrDefault(evt => evt.Action == subscriber);
108                 if (eventSubscription != null)
109                 {
110                     Subscriptions.Remove(eventSubscription);
111                 }
112             }
113         }
114 
115         public virtual bool Contains(Action<TPayload> subscriber)
116         {
117             IEventSubscription eventSubscription;
118             lock (Subscriptions)
119             {
120                 eventSubscription = Subscriptions.Cast<EventSubscription<TPayload>>().FirstOrDefault(evt => evt.Action == subscriber);
121             }
122             return eventSubscription != null;
123         }
124 
125     }
  • 订阅
  • 取消订阅
  • 发布
  • 比较定位

简单用法:

 1 public class Model{
 2     private readonly IEventAggregator eventAggregator;
 3 
 4     this.eventAggregator = eventAggregator;
 5     this.eventAggregator.GetEvent<UpdatedEvent>().Subscribe(this.Updated, ThreadOption.UIThread);
 6 
 7         private void Updated()
 8         {
 9             //Todo Something
10         }
11 
12 }
13 
14     public class UpdatedEvent: CompositePresentationEvent<IDictionary<string, decimal>>
15     {
16     }            

 

 参考资料:

http://www.martinfowler.com/eaaDev/EventAggregator.html

posted @ 2013-04-21 14:42  老鱼_678  阅读(2450)  评论(0编辑  收藏  举报