在Avalonia项目中使用MediatR和MS.DI库实现事件驱动通信

💡 原文中文,约8300字,阅读约需20分钟。
📝

内容提要

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 可以复用大部分事件代码,减少重复工作。

🏷️

标签

➡️

继续阅读