Xamarin Forms Prism 訂閱與發佈EventAggregator
Prism提供了一個事件聚合器之機制,
透過事件聚合器進行訂閱以及發佈,
讓每個模組或功能的耦合性降低提高維護性。
Prism提供的這組訂閱/發佈機制與Xamarin Forms本身的MessagingCenter其實非常類似,
不知道MessagingCenter的可以參考:
https://docs.microsoft.com/zh-tw/xamarin/xamarin-forms/app-fundamentals/messaging-center
不過Prism所提供的事件聚合器功能較完整,使用也較方便。
Prism的事件聚合器是讓訂閱者或發布者去查找特定的EventBase類型,
並且允許多個發布者跟多個訂閱者。如下圖示意:
取得聚合器EventAggregator
EventAggregator在Prism中一開始就會被保留服務在IoC容器中,
並且以IEventAggregator這個介面提供使用。
要使用的時候只要在建構子宣告傳入類型為IEventAggregator的參數即可取得聚合器物件
public MainPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator)
: base(navigationService)
{
}
訂閱事件
不論是訂閱事件還發佈事件,
都是以特定的EventBase類型做為Key去查找,
所以我們需先定義一個自己的EventBase類型,
我們繼承使用已實做的PubSubEvent<T>,T表示該訂閱的事件會拿到類型T的參數。
public class MyEvent: PubSubEvent<string>
{
}
接著當我們要訂閱類型為MyEvent的事件時,可以透過聚合器使用Subscribe方法做訂閱,arg即為發佈者傳遞來的參數:
public MainPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator)
: base(navigationService)
{
eventAggregator.GetEvent<MyEvent>().Subscribe(arg =>
{
this.Text = arg;
});
發佈事件
當我們要發佈事件給上述的訂閱程式,
同樣也必須使用MyEvent類別做發佈,
不然不同類型可是會發不到給訂閱者的喔。
這裡使用Publish方法進行發佈事件。
this.OnFire = new DelegateCommand(() =>
{
eventAggregator.GetEvent<MyEvent>().Publish("我是訂閱通知");
執行序選擇
當訂閱者事件被觸發時,
可以在Subscribe方法中選擇要在哪個執行序做觸發。
假設我們要讓它在UI執行序上,可撰寫如下程式碼
eventAggregator.GetEvent<MyEvent>().Subscribe(arg =>
{
this.Text = arg;
}, ThreadOption.UIThread);
ThreadOption列舉提供了三種
UIThread:在UI執行序上運行。
PublisherThread:與發佈者相同的執行序運行,預設值。
BackgroundThread:在背景執行序運行。
使用強型別事件參考
預設的情況下,訂閱是使用弱型別參考使用事件(weak reference ),
使用弱型別參考的方式使用者不需要取消訂閱,
系統還是會回收不再使用的記憶體。
但如果有短時間內大量發送事件給訂閱者的狀況時,
弱型別參考的方式可能就會有效能問題,
這時我們可以增加傳入一個布林值參數讓它變為強型別參考。
eventAggregator.GetEvent<MyEvent>().Subscribe(arg =>
{
this.Text = arg;
}, ThreadOption.BackgroundThread,true);
但如果使用了強型別參考,就要在不需要使用的時候進行取消訂閱的動作,
系統才有辦法正確地進行記憶體回收的機制,
否則可能會導致記憶體洩漏的問題(memory leak)。
取消訂閱
當我們不需要再接收訂閱的事件時,可以透過Unsubscribe方法取消訂閱。
//...
eventAggregator.GetEvent<MyEvent>().Subscribe(EventFire);
}
public void EventFire(string arg)
{
this.Text = arg;
_eventAggregator.GetEvent<MyEvent>().Unsubscribe(EventFire);
}
簡單的完成範例,按下按鈕發送訂閱,
收到訂閱後更改文字並且取消訂閱。
範例連結
https://github.com/stevenchang0529/Xamarin.Lab.PrismEventAggregator