用途:在 CommunityToolkit.Mvvm 8.x 中,通过发布/订阅在 ViewModel(或任意对象)之间解耦通信,无需互相持有引用。典型场景包括多个 VM 响应登录、主题切换、保存、导航等事件,一个 VM 向另一个 VM 请求值,以及用通道令牌把事件限定到子模块或窗口。
主要能力:默认推荐 WeakReferenceMessenger.Default,接收者以弱引用持有,可被 GC 回收,完整 GC 时自动清理,无需手动 Cleanup()。StrongReferenceMessenger.Default 适合性能敏感场景,但接收者会被固定直到 Unregister,遗漏注册会泄漏。可自定义 IMessenger 实例实现按窗口或作用域隔离,并通过 DI 注入。
消息定义:可继承 ValueChangedMessage<T>,或用 record 自定义结构,也可用空记录作为信号。注册方式有 Lambda 形式(推荐使用 static,避免闭包捕获 this,用 recipient 参数访问实例)和 IRecipient<TMessage> 接口形式。继承 ObservableRecipient 时,OnActivated() 会调用 RegisterAll(this),IsActive 变 true 时自动注册 IRecipient,OnDeactivated() 自动注销;非 ObservableRecipient 需手动 RegisterAll(this)。
发送与通道:用 Send 发送消息,空载荷用无参重载。可通过 int、string、Guid 等可比较值作为令牌将消息限定到特定通道,无令牌消息走默认共享通道,不会送达通道作用域接收者。请求/应答支持 RequestMessage<T> 同步请求、AsyncRequestMessage<T> 异步请求,以及 CollectionRequestMessage<T>、AsyncCollectionRequestMessage<T> 收集所有接收者的应答。
生命周期与限制:即使使用弱引用也可显式 Unregister 或 UnregisterAll 以提升性能。常见坑包括在 Lambda 中捕获 this、强引用接收者未注销、继承消息类型不会触发基类处理器、不同 messenger 实例混用、OnActivated 未触发、以及 Messenger 不处理线程切换,更新 UI 需手动调度。多窗口应用可通过注入不同 IMessenger 隔离广播。完整细节见官方链接与参考资料。