我正在实现 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 中的订阅者没有被触发。然而,在某些情况下,它确实被触发了。
- 我不使用事件的输入。似乎你需要有一些输入类型,所以我只是用了一个虚拟布尔值。我可以摆脱它吗?