WPF MVVM框架 - Prism IEventAggregator 发布订阅

137

WPF Prism 中使用 IEventAggregator 进行发布-订阅

1. IEventAggregator 简介

IEventAggregator 是 Prism 框架中用于模块间松耦合通信的核心组件,通过发布-订阅模式实现。它允许不同模块通过事件进行交互,而无需直接引用彼此。

2. 使用步骤

2.1 定义事件类型

创建自定义事件类,继承 PubSubEvent<T>,其中 T 是事件参数类型:

// 定义事件参数类(可选)
public class MessageEventArgs
{
    public string Message { get; set; }
}

// 定义事件类型类
public class MessageSentEvent : PubSubEvent<MessageEventArgs> { }

2.2 发布事件

在需要触发事件的类(如 ViewModel)中发布事件:

public class PublisherViewModel
{
    private readonly IEventAggregator _eventAggregator;

    // 通过依赖注入获取 IEventAggregator
    public PublisherViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }

    public void SendMessage(string message)
    {
        var payload = new MessageEventArgs { Message = message };
        // 发布事件
        _eventAggregator
                .GetEvent<MessageSentEvent>()
                .Publish(payload);
    }
}

2.3 订阅事件

在需要接收事件的类(如另一个 ViewModel)中订阅事件:

public class SubscriberViewModel : IDisposable
{
    private readonly SubscriptionToken _subscriptionToken;

    public SubscriberViewModel(IEventAggregator eventAggregator)
    {
        // 订阅事件
        _subscriptionToken = eventAggregator
                .GetEvent<MessageSentEvent>()
                .Subscribe(OnMessageReceived);
    }

    private void OnMessageReceived(MessageEventArgs args)
    {
        // 处理接收到的消息
        Console.WriteLine($"收到消息: {args.Message}");
    }

    public void Dispose()
    {
        // 取消订阅(可选)
        _subscriptionToken?.Dispose();
    }
}

3. 订阅选项配置

Subscribe 方法提供多个参数控制订阅行为:

Subscribe(
    OnMessageReceived,
    ThreadOption.PublisherThread, // 指定线程
    keepSubscriberReferenceAlive: false, // 是否保持强引用
    args => args.Message.Contains("重要") // 过滤条件
);

关键参数说明

ThreadOption:

  • PublisherThread: 发布者所在线程(默认)

  • UIThread: UI 线程(通过 SynchronizationContext)

  • BackgroundThread: 后台线程池

keepSubscriberReferenceAlive:

  • false(默认): 弱引用,避免内存泄漏

  • true: 强引用,需手动取消订阅

过滤器: 通过 lambda 表达式过滤事件

4. 注意事项

内存管理:

  • 默认使用弱引用,但若设置了 keepSubscriberReferenceAlive: true,必须手动取消订阅。

  • 推荐在订阅者生命周期结束时调用 Dispose()。

线程安全:

  • 修改 UI 时务必使用 ThreadOption.UIThread。

事件设计:

  • 避免过度使用全局事件,合理划分事件作用域。