Dot-Net
Prism 事件聚合 - 未觸發訂閱者
我正在使用 Prism 實現事件聚合。我有幾個模組,我希望他們每個人都訂閱事件,告訴他們什麼時候被請求。我開始在 shell 中使用訂閱和發布者做一個簡單的範例。那裡沒有問題。現在; 當我將訂閱者移到我的模組時,他們不會被觸發。更奇怪的是它實際上已經工作了幾次——所有這些我都在斷點處等待。所以在我看來這是一些比賽條件,但我不明白為什麼。
*假設:*我不需要在任何地方設置 IEventAggregator - 例如在 IoC 容器中註冊?這是內置在 Prism 中的,因此我只有一個事件聚合器實例,對嗎?
所以,問題基本上是我應該如何/在哪裡/何時設置我的訂閱者。東西等有特定的順序嗎?在我的簡化範例中,我有一個模組 MyModule。Bootstrapper 會將 MyModule 添加到目錄中 - 使其初始化:
catalog.AddModule(typeof(MyModule));MyModule 將儲存聚合器並使用它來訂閱 MyModuleRequestedEvent。它還使用菜單系統資料庫在應用程序菜單中註冊。這個想法是最終點擊菜單應該觸發事件 - 通知 MyModule 它已被請求。然後我希望 MyModule 有責任弄清楚下一步該做什麼。
public MyModule(IEventAggregator aggregator, IApplicationMenuRegistry menu) { _applicationMenu = menu; _aggregator = aggregator; } public void Initialize() { var evnt = _aggregator.GetEvent<MyModuleRequestedEvent>(); evnt.Subscribe(MyModuleRequested); _applicationMenu.RegisterMenuItem("MyModule", evnt); } public void MyModuleRequested(bool b) { MessageBox.Show("MyModule requested"); }現在,我的 shell 中有一個按鈕,它將發布此事件。解析時,shell 會獲得相同的 (?) 事件聚合器。
public Shell(IEventAggregator aggregator) { InitializeComponent(); var evnt = aggregator.GetEvent<MyModuleRequestedEvent>(); EventTriggerButton.Click += (s, e) => evnt.Publish(true); }筆記:
- 已驗證事件已發布。在 shell 中添加訂閱者也會使該訂閱者接收事件。
- 再次; MyModule 中的訂閱者沒有被觸發。然而,奇怪的是,它已經出現過幾次了。
- 我不使用事件的輸入。似乎您需要一些輸入類型,所以我只使用了一個虛擬布爾值。我可以擺脫這個..?
Prism 事件聚合器使用弱引用連結到事件。這是為了防止事件處理程序的記憶體洩漏。
一旦模組初始化程序執行,它就會被釋放,因此您的事件處理程序在事件被觸發之前被銷毀。您可以通過使用訂閱的重載來告訴 Prism 保留事件處理程序。
evnt.Subscribe(MyModuleRequested, true);作為一種模式,我傾向於將任何事件訂閱者放在一個單獨的類中,並從模組的 Initialize 方法中呼叫該類。這樣,當模組仍然被破壞時,事件仍然存在但分開。