本節學習了Event Aggregation事件聚合,這個在PRism中很重要,特別是對于Module間的通信。除了前面介紹的Command可以用于模塊間的通信,還有我們這一節介紹的Event Aggregation(事件聚合).
(一)為什么不用.NET FrameWork中的事件呢?
使用.NET Framework事件是罪簡單和直觀的方式用于非松散耦合需求的組件,屬于對象引用依賴的發布-訂閱模型
(二) EventAggregator事件聚合器
提供了多點傳送發布/訂閱功能。這意味著可能有可以觸發同一事件多個發布者和可以監聽同一事件的訂閱者。
(三)模塊間通信過程簡介
CompositePresentationEvent<TPayload>類實例實現了事件的訂閱和取消,而IEventAggregator實例用來獲取接收CompositePresentationEvent<TPayload>類實例.IEventAggregator實例在每個模塊中含有,這樣模塊間就可以通信了。
(四)下面貼出Prism中Event Aggregation QuickStart的部分代碼:
(1)創建了 CompositePresentationEvent<TPayload>類
在項目中EventAggregation.Infrastructure.Silverlight的FundAddedEvent.cs代碼中,
//定義CompositePresentationEvent<TPayload>類 //(1)該類是泛型類:強制發布者和訂閱者要一種正確的類型實現 發布-訂閱連接 //(2)是唯一繼承自EventBase的類 //(3)因為CompositePresentationEvent<TPayload>往往被多個模塊公用,所以要單獨于 // 其他的模塊新建類庫項目 //FundOrder是這里的TPayLoad類型 public class FundAddedEvent : CompositePresentationEvent<FundOrder> { }(2)事件的發布
在ModuleA.Silverlight項目中的
public class AddFundPresenter { private IAddFundView _view; //IEventAggregator 事件聚合器接口 private IEventAggregator eventAggregator; public AddFundPresenter(IEventAggregator eventAggregator) { this.eventAggregator = eventAggregator; } //事件發布:當用戶添加一個fund基金,事件就被發布 //發布者發布一個事件 //(1)通過IEventAggregator的實例eventAggregator的Publish方法 //(2)指定GetEvent<TEventType>中TEventType為FunAddedEvent void AddFund(object sender, EventArgs e) { FundOrder fundOrder = new FundOrder(); fundOrder.CustomerId = View.Customer; fundOrder.TickerSymbol = View.Fund; if (!string.IsNullOrEmpty(fundOrder.CustomerId) && !string.IsNullOrEmpty(fundOrder.TickerSymbol)) eventAggregator.GetEvent<FundAddedEvent>().Publish(fundOrder); } public IAddFundView View { get { return _view; } set { _view = value; _view.AddFund += AddFund; } } }(3)事件的訂閱
在ModuleB.Silverlight項目中的ActivityPresenter.cs中
public class ActivityPresenter { private string _customerId; private IEventAggregator eventAggregator; private SubscriptionToken subscriptionToken; public ActivityPresenter(IEventAggregator eventAggregator) { this.eventAggregator = eventAggregator; } public void FundAddedEventHandler(FundOrder fundOrder) { Debug.Assert(View != null); View.AddContent(fundOrder.TickerSymbol); } public bool FundOrderFilter(FundOrder fundOrder) { return fundOrder.CustomerId == _customerId; } public IActivityView View { get; set; } public string CustomerId { get { return _customerId; } set { _customerId = value; FundAddedEvent fundAddedEvent = eventAggregator.GetEvent<FundAddedEvent>(); if (subscriptionToken != null) { fundAddedEvent.Unsubscribe(subscriptionToken); } //訂閱事件 //(1)獲取事件聚合器實例 //(2)調用Subscribe方法 // Subscribe方法重載,有不同的作用 // Action<T>: 泛型委托 // ThreadOption:當為PublisherThread時(默認值)能獲取發布者線程 // BackgroundThread時 從.NET Framework線程池上異步獲取事件 // UIThread時 獲取事件從UI線程上。 // keepSubscriberReferenceAlive: 當為true 事件實例是強引用訂閱者,因此不能垃圾回收 // 當為false(默認值)弱引用訂閱者,因此當沒有其他引用時允許垃圾回收釋放訂閱者實例,當訂閱者實例被回收,事件自動取消訂閱 subscriptionToken = fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, false, FundOrderFilter); //lamda表達式寫法 //subscriptionToken = fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, false, FunOrder => FunOrder.CustomerId == this._customerId); View.SetTitle(string.Format(CultureInfo.CurrentCulture, Resources.ActivityTitle, CustomerId)); } } }(五)運行截圖
新聞熱點
疑難解答