在Avalonia项目中使用MediatR和MS.DI库实现事件驱动通信
内容提要
AvaloniaUI是一个跨平台.NET客户端开发框架,支持Windows、Linux、macOS、Android和iOS等多个平台。MediatR是一个开源的中介者模式实现,用于模块间和模块与主程序的通信。本文介绍了如何在Avalonia项目中使用MediatR和Microsoft的依赖注入库来实现事件驱动的通信。通过示例代码演示了请求/响应和通知的使用方式。
延伸解读
MediatR 在 Avalonia 中的集成要点
在 Avalonia 项目中使用 MediatR 需要正确配置 DryIoc 容器。文章指出,高版本 DryIoc.Microsoft.DependencyInjection 必须重写 CreateContainerRules 方法,否则会抛出 MissingMethodException 异常。此外,注册 MediatR 服务时需确保所有包含处理程序的程序集已加载到当前 AppDomain,否则处理程序不会被注册。对于按需加载的模块,需手动添加程序集引用。
请求/响应与通知的差异
MediatR 支持两种消息传递方式:请求/响应和通知。请求/响应是一对一模式,一个请求只能被一个处理程序处理,即使注册了多个处理程序,也只会触发其中一个(通常按注册顺序)。通知是一对多模式,一个通知可以被多个处理程序处理,所有注册的处理程序都会被执行。文章示例中,主工程和模块都注册了请求处理程序,但只有主工程被触发;而通知则两个处理程序都弹出了提示。
为何选择 MediatR 而非 Prism 事件聚合器
文章作者在开发在线版(Blazor)和桌面版(Avalonia)工具时,选择 MediatR 而非 Prism 的事件聚合器,主要原因是 MediatR 可以复用大部分事件代码。由于两个版本共享业务逻辑,使用 MediatR 能够减少重复代码,提高开发效率。此外,MediatR 的进程内消息传递机制简单轻量,无需额外依赖,适合模块化应用中的通信需求。
Q&A
MediatR 是什么?它有什么作用?
MediatR 是 .NET 中的开源简单中介者模式实现,通过进程内消息传递机制进行请求/响应、命令、查询、通知和事件的消息传递,并通过泛型支持消息的智能调度。它适用于模块之间以及模块与主程序之间的通信。
MediatR 支持哪两种消息传递方式?它们有什么区别?
MediatR 支持 Request/Response 和 Notification 两种方式。Request/Response 用于一个单独的 Handler,发出一个 Request 会得到一个 Response,类似于 HTTP 的请求/响应;Notification 用于多个 Handler,调用者发出一次,可以有多个处理者参与处理。
在 Avalonia 项目中使用 MediatR 需要安装哪些 NuGet 包?
需要安装 Prism.DryIoc.Avalonia 作为依赖注入容器,MediatR 处理事件的发布和订阅,以及 DryIoc.Microsoft.DependencyInjection 将 MediatR 集成到 DryIoc 容器中。
如何在 Avalonia 项目中配置 DryIoc 容器并注册 MediatR 服务?
在 App.axaml.cs 中重写 CreateContainerRules、CreateContainerExtension 和 RegisterRequiredTypes 方法。CreateContainerRules 返回自定义规则;CreateContainerExtension 创建 DryIoc 容器并调用 WithDependencyInjectionAdapter;RegisterRequiredTypes 中通过 ConfigureServices 创建 ServiceCollection,调用 AddMediatR 并传入程序集列表来注册处理程序,最后用 container.Populate(services) 填充容器。
MediatR 中的请求和通知在定义上有什么区别?
请求和通知的定义结构相似,但实现的接口不同。请求实现 IRequest<T> 或 IRequest 接口,通知实现 INotification 接口。例如,TestRequest 实现 IRequest<string>,TestNotification 实现 INotification。
在 Avalonia 项目中如何触发 MediatR 的请求和通知?
在 ViewModel 中通过依赖注入获取 ISender 和 IPublisher 实例。调用 ISender.Send 方法发送请求并获取响应,调用 IPublisher.Publish 方法发布通知。例如,在 SlugifyViewModel 中,ExecuteMediatRRequestAsync 方法使用 Sender.Send 发送 TestRequest,ExecuteMediatRNotificationAsync 方法使用 Publisher.Publish 发布 TestNotification。
为什么在 Avalonia 项目中选择 MediatR 而不是 Prism 的事件聚合器?
因为开发者同时开发了在线版(Blazor)和跨平台桌面版(AvaloniaUI),使用 MediatR 可以复用大部分事件代码,减少重复工作。