CodeWF.EventBus:轻量级事件总线,让通信更流畅

1. CodeWF.EventBus

EventBus(事件总线),用于解耦模块之间的通讯。本库(CodeWF.EventBus)适用于进程内消息传递(无其他外部依赖),与大家普遍使用的MediatR部分类似,但MediatR库侧重于ASP.NET Core设计使用,而本库也有点点优势:

  1. 设计可在各种模板项目使用,如WPF、Winform、AvaloniaUI、ASP.NET Core等,主要参考了Prism.Events设计;
  2. 参考MASA Framework增强消息处理能力:
internal class MessageHandler
{[EventHandler(Order = 3)]private void ReceiveAutoCreateProductMessage3(CreateProductMessage message){AddLog($"收到自动订阅消息3({message}”");}[EventHandler(Order = 1)]private void ReceiveAutoDeleteProductMessage(DeleteProductMessage message){AddLog($"收到自动订阅消息({message}”");}[EventHandler(Order = 2)]private void ReceiveAutoCreateProductMessage2(CreateProductMessage message){AddLog($"收到自动订阅消息2({message}”");}
}

2. 怎么使用事件总线?

首先定义消息类,消息需要继承自CodeWF.EventBus.Message

public class CreateProductMessage : CodeWF.EventBus.Message
{public string Name { get; }public CreateProductMessage(object sender, string name) : base(sender){Name = name;}public override string ToString(){return $"创建产品消息-》产品名称:{Name}";}
}public class DeleteProductMessage : CodeWF.EventBus.Message
{public string Id { get; }public DeleteProductMessage(object sender, string id) : base(sender){Id = id;}public override string ToString(){return $"删除产品消息-》产品Id:{Id}";}
}

定义好消息,这里我们有两种方式使用事件总线,非IOC和IOC方式:

  1. 非IOC方式:需要安装CodeWF.EventBus包,适用于未使用IOC的模板程序,比如WPF、Winform、AvaloniaUI、控制台程序,当然ASP.NET Core也能用。
  2. IOC方式:需要安装CodeWF.AspNetCore.EventBus包,适合于在ASP.NET Core程序中使用。

2.1. 非IOC方式使用

适合于未使用IOC方式使用事件总线,比如在WPF、Winform、AvaloniaUI、控制台等程序中直接使用事件帮助类的静态实例,下面是使用步骤。

创建项目(不限于项目类型,比如控制台程序),通过NuGet引入CodeWF.EventBus包:

Install-Package CodeWF.EventBus -Version 1.0.1

创建消息处理程序,这里参考了Prism.Events设计,可订阅消息、取消订阅消息、发布消息,适合于手工指定处理方法:

internal class MessageHandler
{internal void ManuSubscribe(){Messenger.Default.Subscribe<CreateProductMessage>(this, ReceiveManuCreateProductMessage);Messenger.Default.Subscribe<DeleteProductMessage>(this, ReceiveManuDeleteProductMessage);}internal void ManuUnsubscribe(){Messenger.Default.Unsubscribe<CreateProductMessage>(this, ReceiveManuCreateProductMessage);Messenger.Default.Unsubscribe<DeleteProductMessage>(this, ReceiveManuDeleteProductMessage);}internal void Publish(){Messenger.Default.Publish(this, new CreateProductMessage(this, $"{DateTime.Now:HHmmss}号产品"));Messenger.Default.Publish(this, new DeleteProductMessage(this, $"{DateTime.Now:HHmmss}号"));}void ReceiveManuCreateProductMessage(CreateProductMessage message){AddLog($"收到手动注册的{message}");}void ReceiveManuDeleteProductMessage(DeleteProductMessage message){AddLog($"收到手动注册的{message}");}private void AddLog(string message){Console.WriteLine($"{DateTime.Now:HH:mm:ss fff} {message}\r\n");}
}

最后是消息使用:

using ConsoleDemo.EventBus;var handler = new MessageHandler();Console.WriteLine("1、未注册时发布消息:");
handler.Publish();
Console.WriteLine();Console.WriteLine("2、手动注册后发布消息:");
handler.ManuSubscribe();
handler.Publish();Console.WriteLine("3、取消手动注册后发布消息:");
handler.ManuUnsubscribe();
handler.Publish();Console.ReadKey();

如果消息较多,也可使用自动注册消息处理方法,我们修改处理程序:

internal class MessageHandler
{internal void AutoSubscribe(){Messenger.Default.Subscribe(this);}internal void AutoUnsubscribe(){Messenger.Default.Unsubscribe(this);}internal void Publish(){Messenger.Default.Publish(this, new CreateProductMessage(this, $"{DateTime.Now:HHmmss}号产品"));Messenger.Default.Publish(this, new DeleteProductMessage(this, $"{DateTime.Now:HHmmss}号"));}[EventHandler(Order = 3)]private void ReceiveAutoCreateProductMessage3(CreateProductMessage message){AddLog($"收到自动订阅消息3({message}”");}[EventHandler(Order = 1)]private void ReceiveAutoDeleteProductMessage(DeleteProductMessage message){AddLog($"收到自动订阅消息({message}”");}[EventHandler(Order = 2)]private void ReceiveAutoCreateProductMessage2(CreateProductMessage message){AddLog($"收到自动订阅消息2({message}”");}private void AddLog(string message){Console.WriteLine($"{DateTime.Now:HH:mm:ss fff} {message}\r\n");}
}

[EventHandler(Order = 0)] 定义消息的执行顺序。每个消息都可以匹配多个处理程序。一个类中可以有多个消息处理方法,可以订阅同一个消息,也可以订阅不同的消息。

支持消息处理程序的注销:

  1. 注销指定处理程序:Messenger.Default.Unsubscribe<CreateProductMessage>(this, ReceiveManuCreateProductMessage)
  2. 注销指定类的所有处理程序:Messenger.Default.Unsubscribe(this)

消息使用:

using ConsoleDemo.EventBus;var handler = new MessageHandler();Console.WriteLine("1、未注册时发布消息:");
handler.Publish();
Console.WriteLine();Console.WriteLine("2、自动注册后发布消息:");
handler.AutoSubscribe();
handler.Publish();Console.WriteLine("3、取消自动注册后发布消息:");
handler.AutoUnsubscribe();
handler.Publish();Console.ReadKey();

2.2. IOC方式使用

适合于在ASP.NET Core程序中使用,下面是使用步骤。

创建项目(ASP.NET Core模块项目,比如Web API、MVC、Razor Page、Blazor Server等),通过NuGet引入CodeWF.AspNetCore.EventBus:

Install-Package CodeWF.AspNetCore.EventBus -Version 1.0.1

创建消息处理程序,处理类中可以正常使用构造函数注入IOC服务:

public class MessageHandler
{private readonly ITimeService timeService;public MessageHandler(ITimeService timeService){this.timeService = timeService;}[EventHandler(Order = 3)]public void ReceiveAutoCreateProductMessage3(CreateProductMessage message){AddLog($"收到消息3({message}”");}[EventHandler(Order = 1)]public void ReceiveAutoDeleteProductMessage(DeleteProductMessage message){AddLog($"收到消息({message}”");}[EventHandler(Order = 2)]public void ReceiveAutoCreateProductMessage2(CreateProductMessage message){AddLog($"收到消息2({message}”");}private void AddLog(string message){Console.WriteLine($"{timeService.GetTime()}: {message}\r\n");}
}
public interface ITimeService
{string GetTime();
}public class TimeService : ITimeService
{public string GetTime(){return DateTime.Now.ToString("HH:mm:ss fff");}
}

在Program中注册事件总线:

using CodeWF.AspNetCore.EventBus;var builder = WebApplication.CreateBuilder(args);builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();// 用于测试事件处理类正常使用IOC功能
builder.Services.AddSingleton<ITimeService, TimeService>();// 1、注册事件总线,将标注`EventHandler`特性方法的类采用单例方式注入IOC容器
builder.Services.AddEventBus();var app = builder.Build();// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI();
}app.UseAuthorization();
app.MapControllers();// 2、将上面已经注入IOC容器的类取出、关联处理方法到事件总线管理
app.UseEventBus();app.Run();

在控制器或其他服务可以发布消息,上面的处理程序会接收处理:

[ApiController]
[Route("[controller]")]
public class EventController : ControllerBase
{private readonly ILogger<EventController> _logger;private readonly IMessenger _messenger;public EventController(ILogger<EventController> logger, IMessenger messenger){_logger = logger;_messenger = messenger;}[HttpPost]public void Add(){_messenger.Publish(this, new CreateProductMessage(this, $"{DateTime.Now:HHmmss}号产品"));}[HttpDelete]public void Delete(){_messenger.Publish(this, new DeleteProductMessage(this, $"{DateTime.Now:HHmmss}号"));}
}

3. 总结

CodeWF.EventBus,一款灵活的事件总线库,实现模块间解耦通信。支持多种.NET项目类型,如WPF、WinForms、ASP.NET Core等。采用简洁设计,轻松实现事件的发布与订阅。通过有序的消息处理,确保事件得到妥善处理。简化您的代码,提升系统可维护性。立即体验CodeWF.EventBus,让事件处理更加高效!

仓库地址是https://github.com/dotnet9/CodeWF.EventBus,开发过程中参考不少开源项目,他们是:

  1. Prism.Events
  2. MediatR
  3. MASA Framework

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/25609.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dish-TS: 缓解分布转移的一般范例 时间序列预测

摘要 时间序列预测(TSF)中的分布移位(即序列分布随时间的变化)在很大程度上阻碍了TSF模型的性能。现有的关于时间序列中分布变化的研究大多局限于分布的量化&#xff0c;更重要的是&#xff0c;忽视了回望窗和地平线窗之间的潜在变化。为了应对上述挑战&#xff0c;我们系统地…

网络编程之XDP技术应用

一、AF_XDP介绍 在上文中介绍了XDP技术&#xff0c;XDP技术的基本原理已经明白&#xff0c;但有一个问题&#xff0c;一个技术如何落地&#xff0c;如何在实际中应用&#xff1f;这就需要有一个承载其的具体的形式。举一个例子&#xff0c;网络编程一般使用Socket方式&#xf…

VM-Import 导入 Debian 12 系统

介绍 之前介绍过使用 VM-Import 导入 Windows 系统到 AWS 环境启动 EC2 实例, 本文将介绍如何导入 Debian 12 系统. 本地虚拟化使用 VMWare Workstation 创建虚拟机安装和准备 Debian 12 系统, 导出 OVA 文件后上传到 S3 存储桶中再使用 AWSCLI 执行 VM-Import 命令实现导入过…

【Vue】获取模块内的state数据

目标&#xff1a; 掌握模块中 state 的访问语法 尽管已经分模块了&#xff0c;但其实子模块的状态&#xff0c;还是会挂到根级别的 state 中&#xff0c;属性名就是模块名 使用模块中的数据 直接通过模块名访问 $store.state.模块名.xxx 通过 mapState 映射&#xff1a; 默认…

mac免费的ntfs软件哪个好 MAC读取NTFS硬盘格式

对于苹果用户来说&#xff0c;Mac电脑和移动硬盘已经成为日常工作中不可缺少的一部分&#xff0c;但有时我发现Mac打开移动硬盘只能读取无法写入&#xff0c;这是由于所连接的移动硬盘为NTFS格式。我们可以通过对硬盘格式化为Mac正常读写格式&#xff0c;或使用数据读写软件对N…

DNS协议 | NAT技术 | 代理服务器

目录 一、DNS协议 1、DNS背景 2、DNS协议 域名 域名解析 二、NAT技术 1、NAT技术 2、NAPT技术 3、NAT技术的缺陷 三、代理服务器 1、正向代理服务器 2、反向代理服务器 一、DNS协议 域名系统&#xff08;Domain Name System&#xff0c;缩写&#xff1a;DNS&#…

Zabbix配置中文显示及乱码问题

页面配置为中文显示 在zabbix 5.0版本开始用户菜单更改为左侧栏显示&#xff0c;找到并点击 User Settings&#xff0c;Language 修改语言为 Chinese (zh_CN) 即可。 PS&#xff1a;一般在部署后初始配置时&#xff0c;未找到 Chinese (zh_CN) 这一项&#xff0c;修改如下&…

深度学习中embedding层的理解

Embedding层作用 在深度学习领域中&#xff0c;Embedding层扮演着至关重要的角色&#xff0c;尤其在处理文本数据或类别数据。Embedding层的功能有两个&#xff1a; 1. 将高维稀疏的输入数据&#xff08;如单词、类别标签等&#xff09;转换为低维稠密的向量表示&#xff0c;…

数 据 类 型

概述 Java 是强类型语言。 每一种数据都定义了明确的数据类型&#xff0c;在内存中分配了不同大小的内存空间&#xff08;字节&#xff09;。 Java 中一共有 8 种基本类型&#xff08;primitive type&#xff09;&#xff0c;包括 4 种整型、2 种浮点型、1 种字符类型&#…

Vulnhub靶机之reven 1

一、信息收集 nmap扫描网段&#xff0c;靶机地址为192.168.145.129。 nmap -sP 192.168.145.* 扫一下端口&#xff0c;开放了22、80、111、50967。 nmap -sT -T4 -p1-65535 192.168.145.129 再看一下目录情况&#xff0c;发现一个疑似后台登录的地址。 dirsearch -u http://…

【C++修行之道】类和对象(六)再谈构造函数(初始化列表)| explicit关键字 | static成员 | 友元|匿名对象|拷贝时一些编译器优化

目录 一、再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1. 所有的成员,既可以在初始化列表初始化,也可以在函数体内初始化 2. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次) 3. 类中包含以下成员&#xff0c;必须放在初始化列表位置进行初始化&…

N32G45XVL-STB之移植LVGL(lvgl-8.2.0)

目录 概述 1 软硬件介绍 1.1 软件版本信息 1.2 ST7796-LCD 1.3 MCU IO与LCD PIN对应关系 2 认识LVGL 2.1 LVGL官网 2.2 LVGL库文件下载 3 移植LVGL 3.1 准备移植文件 3.2 添加lvgl库文件到项目 3.2.1 src下的文件 3.2.2 examples下的文件 3.2.3 配置文件路径 3.2…

VS2019专业版 C#和MFC安装

1. VS2019专业版下载地址 https://learn.microsoft.com/en-us/visualstudio/releases/2019/history 2.安装 C# 部分 MFC部分

【Linux】进程6——环境变量

1.什么是环境变量 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 比如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#xff0c;但是照样可以链接成功&…

[知识点] 内存顺序属性的用途和行为

C标准库中定义了以下几种内存顺序属性&#xff1a; std::memory_order_relaxedstd::memory_order_consumestd::memory_order_acquirestd::memory_order_releasestd::memory_order_acq_relstd::memory_order_seq_cst 1. std::memory_order_relaxed 定义&#xff1a;不提供同步…

通过 Python+Nacos实现微服务,细解微服务架构

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 背景 一直以来的想法比较多&#xff0c;然后就用Python编写各种代码脚本。很多…

C++青少年简明教程:文件

C青少年简明教程&#xff1a;文件 文件是指存储在计算机文件系统中的数据集合。文件可以包含各种类型的信息&#xff0c;例如文本、图像、音频视频等。在 C中&#xff0c;文件是一种数据流&#xff0c;可以用于读取或写入数据。C提供了一系列的文件操作函数&#xff0c;用于实现…

这个国际档案日,大比武放榜、直播预约、课件下载,一样都不能少!

关注我们 - 数字罗塞塔计划 - 2024年6月9日第十七个国际档案日来临&#xff0c;数字罗塞塔计划放大招&#xff1a;第二届大比武活动榜单揭晓、ARCHE-2024上海智慧档案高峰论坛直播预约、2024上半年度课件大礼包下载。如此大礼&#xff0c;岂能错过&#xff1f; PART.01 榜单…

【LeetCode 第 401 场周赛】K秒后第 N 个元素的值

文章目录 1. K秒后第 N 个元素的值&#x1f197; 1. K秒后第 N 个元素的值&#x1f197; 题目链接&#x1f517; &#x1f427;解题思路&#xff1a; 前缀和 小规律&#x1f34e; &#x1f34e; 从上图观察可知&#xff0c;规律一目了然&#xff0c;arr[i] arr[i] 对上一…

2024-6-9

今日安排&#xff1a; 学校的课程作业windows SEH 机制简单入门windows 用户态 pwn / 内核态入门 计网实验报告 && 网安实验报告继续审计 nf_tables 源码&#xff0c;主要看 active 相关逻辑。复现 CVE-2022-32250 这个漏洞【 && iptables 相关学习】♥♥♥♥…