我正在使用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(); 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(); EventTriggerButton.Click += (s, e) => evnt.Publish(true); }
笔记:
已验证该事件已发布.在shell中添加订户也会使该订户接收该事件.
再次; MyModule中的订户未被触发.然而,奇怪的是,有几次.
我没有使用事件的输入.看起来你需要一些输入类型,所以我只是带着一个虚拟布尔.我可以摆脱这个......?
Cameron MacF.. 30
Prism Event Aggregator使用弱引用链接到事件.这是为了防止事件处理程序的内存泄漏.
一旦模块初始化程序运行它就被处理掉了,所以你的事件处理程序在事件被触发之前就被销毁了.您可以通过使用Subscribe的重载来告诉Prism保持事件处理程序.
evnt.Subscribe(MyModuleRequested, true);
作为一种模式,我倾向于将任何事件订阅者放在一个单独的类中,并从模块Initialize方法中调用该类.这样,事件保持活跃但在模块仍然被破坏时分开.
Prism Event Aggregator使用弱引用链接到事件.这是为了防止事件处理程序的内存泄漏.
一旦模块初始化程序运行它就被处理掉了,所以你的事件处理程序在事件被触发之前就被销毁了.您可以通过使用Subscribe的重载来告诉Prism保持事件处理程序.
evnt.Subscribe(MyModuleRequested, true);
作为一种模式,我倾向于将任何事件订阅者放在一个单独的类中,并从模块Initialize方法中调用该类.这样,事件保持活跃但在模块仍然被破坏时分开.