首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Prism 事件機制深度解析:CompositeWpfEvent 與 EventAggregator 實現鬆耦合通訊

     編輯:關於.NET

前言:為何 Prism 不直接使用 C# Event 或 WPF RoutedEvent?

在 Prism 架構中,事件系統並未直接採用 C# 原生的 event 關鍵字,也非 WPF 的 RoutedEvent,而是自行打造了 CompositeWpfEvent。核心原因在於解耦事件發布者與訂閱者。在模組化應用中,模組 A 需訂閱模組 B 的事件,但兩者不直接引用,而是透過依賴注入(DI)溝通,編譯期無法完成事件訂閱。因此,Prism 引入 EventAggregator(事件聚合器) 作為中介,統一管理事件發布與訂閱,形成多對多的鬆耦合關係。

值得注意的是,CompositeWpfEvent 專注於模組間通訊,並非要取代 C# Event 或 RoutedEvent,兩者處於不同架構層級。

EventAggregator:事件聚合器模式實作

Prism 採用 EventAggregator 模式(參考 Martin Fowler 定義),提供統一事件實例存取介面:

public interface IEventAggregator {
    TEventType GetEvent<TEventType>() where TEventType : EventBase;
}

所有發布者與訂閱者均透過 IEventAggregator 取得事件實例,彼此無需知曉對方存在。同一事件可有多個發布者、多個訂閱者。若需指定發布者身分(類似傳統 sender 參數),可透過事件負載(TPayload)傳遞任意類型資料。

在 Prism 中,EventAggregator 作為基礎服務註冊至 DI 容器,供各模組透過建構子注入取用。

建立與發布自訂事件

  1. 定義事件負載類別:可為簡單型別或自訂類別,無需繼承 EventArgs。
    public class LoginSucceededEventArgs { }
  2. 建立事件類別繼承 CompositeWpfEvent<T>:
    public class LoginSucceededEvent : CompositeWpfEvent<LoginSucceededEventArgs> { }
  3. 透過 EventAggregator 發布事件:
    eventAggregator.GetEvent<LoginSucceededEvent>().Publish(new LoginSucceededEventArgs());

CompositeWpfEvent 內建觀察者模式,提供訂閱、取消訂閱等方法,避免為每個事件手動實作。相較 C# Event,它提供更進階功能:

  • 執行緒選項:發布執行緒(PublisherThread)、UI 執行緒(UIThread)、背景執行緒(BackgroundThread)。
  • 引用模式:預設弱引用(不阻礙 GC),可指定強引用(需手動取消訂閱避免記憶體洩漏)。
  • 事件篩選器:訂閱時可提供 Predicate<TPayload>,僅接收符合條件的事件通知。

訂閱事件與取消訂閱

呼叫 Subscribe 方法,參數包含回調委派、執行緒選項、是否保持強引用、篩選器。回傳 SubscriptionToken 供後續 Unsubscribe 使用。

public virtual SubscriptionToken Subscribe(
    Action<TPayload> action,
    ThreadOption threadOption,
    bool keepSubscriberReferenceAlive,
    Predicate<TPayload> filter)

與 CAB 事件模型比較

CAB 使用 Attribute + Magic String(如 event://MyEventSignature)標記發布/訂閱,缺點明顯:

  • 編譯期無法檢查字串正確性,易拼寫錯誤。
  • 需透過反射掃描 Attribute,效能較差。

Prism 採強型別事件類別(繼承 CompositeWpfEvent),編譯期即可驗證,效能更佳,且支援上述進階功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved