在 Prism 框架中,EventAggregator 的主要作用是在应用程序的不同部分之间实现消息传递,使得各个模块或视图之间无需直接引用就能进行通信。它基于发布 - 订阅(Publish-Subscribe)模式,提供了一种集中管理事件的机制。具体来说,任何模块或视图都可以通过 EventAggregator 发布特定类型的事件,而其他对该事件感兴趣的模块或视图可以订阅该事件,当事件被发布时,所有订阅该事件的对象都会收到通知并执行相应的处理逻辑。
首先,你需要创建一个继承自 PubSubEvent
的事件类,其中 T 是你要传递的数据类型。例如:
public class UserUpdatedEvent : PubSubEvent<User>
{
}
这里,UserUpdatedEvent
是一个事件类,它携带了一个 User
对象作为参数。
要在某个地方发布事件,你需要获取 IEventAggregator
实例,并调用其 GetEvent
方法来获取特定类型的事件对象,然后调用 Publish()
方法发布事件。
public class UserService
{
private readonly IEventAggregator _eventAggregator;
public UserService(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
public void UpdateUser(User user)
{
// 更新用户逻辑...
// 发布用户更新事件
_eventAggregator.GetEvent<UserUpdatedEvent>().Publish(user);
}
}
为了订阅事件,你需要在构造函数或其他初始化方法中获取 IEventAggregator
实例,并调用 GetEvent
方法来获取特定类型的事件对象,然后调用 Subscribe()
方法订阅该事件。
public class UserProfileViewModel
{
private readonly IEventAggregator _eventAggregator;
public UserProfileViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
// 订阅用户更新事件
_eventAggregator.GetEvent<UserUpdatedEvent>().Subscribe(OnUserUpdated);
}
private void OnUserUpdated(User user)
{
// 处理用户更新逻辑...
}
}
默认情况下,事件处理是同步的。如果你希望异步处理事件,可以使用 SubscribeAsync()
方法:
_eventAggregator.GetEvent<UserUpdatedEvent>().SubscribeAsync(async (user) =>
{
await Task.Run(() => { /* 异步处理逻辑 */ });
});
你还可以指定事件应该在哪一个线程上执行,比如 UI 线程:
_eventAggregator.GetEvent<UserUpdatedEvent>().Subscribe(OnUserUpdated, ThreadOption.UIThread);
有时你可能只想处理某些特定条件下的事件。你可以通过传递一个过滤器函数来实现这一点:
_eventAggregator.GetEvent<UserUpdatedEvent>().Subscribe(OnUserUpdated,
threadOption: ThreadOption.PublisherThread,
keepSubscriberReferenceAlive: false,
filter: user => user.Id == currentUserId);
在这个例子中,只有当 user.Id
等于 currentUserId
时,才会触发 OnUserUpdated
方法。
EventAggregator
是 Prism 框架中实现模块间通信的重要机制之一,具有以下优点:
通过合理利用 EventAggregator
,你可以构建出更加灵活、易于维护的应用程序架构。无论是简单的消息传递还是复杂的模块间通信,EventAggregator
都能提供强大的支持。
订阅者经常需要更新UI元素以响应事件。在WPF中,只有UI线程可以更新UI元素。
默认情况下,订阅者接收发布者线程上的事件。如果发布者从UI线程发送事件,订阅者可以更新UI。但是,如果发布者的线程是后台线程,订阅者可能无法直接更新UI元素。在这种情况下,订阅者需要使用Dispatcher类在UI线程上调度更新。
Prism库提供的PubSubEvent可以通过允许订阅者自动接收UI线程上的事件来提供帮助。订阅者在订阅期间指示这一点,如下面的代码示例所示。
public class MainPageViewModel
{
public MainPageViewModel(IEventAggregator ea)
{
ea.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews, ThreadOption.UIThread);
}
void ShowNews(string companySymbol)
{
//implement logic
}
}
以下选项可用于ThreadOption:
PublisherThread:使用此设置接收发布者线程上的事件。这是默认设置。
BackgroundThread:使用此设置来异步接收。net框架线程池线程上的事件。
UIThread:使用此设置接收UI线程上的事件。