翼度科技»论坛 编程开发 .net 查看内容

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

3

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
1. CodeWF.EventBus

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

  • 设计可在各种模板项目使用,如WPF、Winform、AvaloniaUI、ASP.NET Core等,主要参考了Prism.Events设计;
  • 参考MASA Framework增强消息处理能力:
  1. internal class MessageHandler
  2. {
  3.     [EventHandler(Order = 3)]
  4.     private void ReceiveAutoCreateProductMessage3(CreateProductMessage message)
  5.     {
  6.         AddLog($"收到自动订阅消息3({message}”");
  7.     }
  8.     [EventHandler(Order = 1)]
  9.     private void ReceiveAutoDeleteProductMessage(DeleteProductMessage message)
  10.     {
  11.         AddLog($"收到自动订阅消息({message}”");
  12.     }
  13.     [EventHandler(Order = 2)]
  14.     private void ReceiveAutoCreateProductMessage2(CreateProductMessage message)
  15.     {
  16.         AddLog($"收到自动订阅消息2({message}”");
  17.     }
  18. }
复制代码
2. 怎么使用事件总线?

首先定义消息类,消息需要继承自CodeWF.EventBus.Message:
  1. public class CreateProductMessage : CodeWF.EventBus.Message
  2. {
  3.     public string Name { get; }
  4.     public CreateProductMessage(object sender, string name) : base(sender)
  5.     {
  6.         Name = name;
  7.     }
  8.     public override string ToString()
  9.     {
  10.         return $"创建产品消息-》产品名称:{Name}";
  11.     }
  12. }
  13. public class DeleteProductMessage : CodeWF.EventBus.Message
  14. {
  15.     public string Id { get; }
  16.     public DeleteProductMessage(object sender, string id) : base(sender)
  17.     {
  18.         Id = id;
  19.     }
  20.     public override string ToString()
  21.     {
  22.         return $"删除产品消息-》产品Id:{Id}";
  23.     }
  24. }
复制代码
定义好消息,这里我们有两种方式使用事件总线,非IOC和IOC方式:

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

适合于未使用IOC方式使用事件总线,比如在WPF、Winform、AvaloniaUI、控制台等程序中直接使用事件帮助类的静态实例,下面是使用步骤。
创建项目(不限于项目类型,比如控制台程序),通过NuGet引入CodeWF.EventBus包:
  1. Install-Package CodeWF.EventBus -Version 1.0.1
复制代码
创建消息处理程序,这里参考了Prism.Events设计,可订阅消息、取消订阅消息、发布消息,适合于手工指定处理方法:
  1. internal class MessageHandler
  2. {
  3.     internal void ManuSubscribe()
  4.     {
  5.         Messenger.Default.Subscribe<CreateProductMessage>(this, ReceiveManuCreateProductMessage);
  6.         Messenger.Default.Subscribe<DeleteProductMessage>(this, ReceiveManuDeleteProductMessage);
  7.     }
  8.     internal void ManuUnsubscribe()
  9.     {
  10.         Messenger.Default.Unsubscribe<CreateProductMessage>(this, ReceiveManuCreateProductMessage);
  11.         Messenger.Default.Unsubscribe<DeleteProductMessage>(this, ReceiveManuDeleteProductMessage);
  12.     }
  13.     internal void Publish()
  14.     {
  15.         Messenger.Default.Publish(this, new CreateProductMessage(this, $"{DateTime.Now:HHmmss}号产品"));
  16.         Messenger.Default.Publish(this, new DeleteProductMessage(this, $"{DateTime.Now:HHmmss}号"));
  17.     }
  18.     void ReceiveManuCreateProductMessage(CreateProductMessage message)
  19.     {
  20.         AddLog($"收到手动注册的{message}");
  21.     }
  22.     void ReceiveManuDeleteProductMessage(DeleteProductMessage message)
  23.     {
  24.         AddLog($"收到手动注册的{message}");
  25.     }
  26.     private void AddLog(string message)
  27.     {
  28.         Console.WriteLine($"{DateTime.Now:HH:mm:ss fff} {message}\r\n");
  29.     }
  30. }
复制代码
最后是消息使用:
  1. using ConsoleDemo.EventBus;
  2. var handler = new MessageHandler();
  3. Console.WriteLine("1、未注册时发布消息:");
  4. handler.Publish();
  5. Console.WriteLine();
  6. Console.WriteLine("2、手动注册后发布消息:");
  7. handler.ManuSubscribe();
  8. handler.Publish();
  9. Console.WriteLine("3、取消手动注册后发布消息:");
  10. handler.ManuUnsubscribe();
  11. handler.Publish();
  12. Console.ReadKey();
复制代码
如果消息较多,也可使用自动注册消息处理方法,我们修改处理程序:
  1. internal class MessageHandler
  2. {
  3.     internal void AutoSubscribe()
  4.     {
  5.         Messenger.Default.Subscribe(this);
  6.     }
  7.     internal void AutoUnsubscribe()
  8.     {
  9.         Messenger.Default.Unsubscribe(this);
  10.     }
  11.     internal void Publish()
  12.     {
  13.         Messenger.Default.Publish(this, new CreateProductMessage(this, $"{DateTime.Now:HHmmss}号产品"));
  14.         Messenger.Default.Publish(this, new DeleteProductMessage(this, $"{DateTime.Now:HHmmss}号"));
  15.     }
  16.     [EventHandler(Order = 3)]
  17.     private void ReceiveAutoCreateProductMessage3(CreateProductMessage message)
  18.     {
  19.         AddLog($"收到自动订阅消息3({message}”");
  20.     }
  21.     [EventHandler(Order = 1)]
  22.     private void ReceiveAutoDeleteProductMessage(DeleteProductMessage message)
  23.     {
  24.         AddLog($"收到自动订阅消息({message}”");
  25.     }
  26.     [EventHandler(Order = 2)]
  27.     private void ReceiveAutoCreateProductMessage2(CreateProductMessage message)
  28.     {
  29.         AddLog($"收到自动订阅消息2({message}”");
  30.     }
  31.     private void AddLog(string message)
  32.     {
  33.         Console.WriteLine($"{DateTime.Now:HH:mm:ss fff} {message}\r\n");
  34.     }
  35. }
复制代码
[EventHandler(Order = 0)] 定义消息的执行顺序。每个消息都可以匹配多个处理程序。一个类中可以有多个消息处理方法,可以订阅同一个消息,也可以订阅不同的消息。
支持消息处理程序的注销:

  • 注销指定处理程序:Messenger.Default.Unsubscribe(this, ReceiveManuCreateProductMessage)
  • 注销指定类的所有处理程序:Messenger.Default.Unsubscribe(this)
消息使用:
  1. using ConsoleDemo.EventBus;
  2. var handler = new MessageHandler();
  3. Console.WriteLine("1、未注册时发布消息:");
  4. handler.Publish();
  5. Console.WriteLine();
  6. Console.WriteLine("2、自动注册后发布消息:");
  7. handler.AutoSubscribe();
  8. handler.Publish();
  9. Console.WriteLine("3、取消自动注册后发布消息:");
  10. handler.AutoUnsubscribe();
  11. handler.Publish();
  12. Console.ReadKey();
复制代码
2.2. IOC方式使用

适合于在ASP.NET Core程序中使用,下面是使用步骤。
创建项目(ASP.NET Core模块项目,比如Web API、MVC、Razor Page、Blazor Server等),通过NuGet引入CodeWF.AspNetCore.EventBus:
  1. Install-Package CodeWF.AspNetCore.EventBus -Version 1.0.1
复制代码
创建消息处理程序,处理类中可以正常使用构造函数注入IOC服务:
  1. public class MessageHandler
  2. {
  3.     private readonly ITimeService timeService;
  4.     public MessageHandler(ITimeService timeService)
  5.     {
  6.         this.timeService = timeService;
  7.     }
  8.     [EventHandler(Order = 3)]
  9.     public void ReceiveAutoCreateProductMessage3(CreateProductMessage message)
  10.     {
  11.         AddLog($"收到消息3({message}”");
  12.     }
  13.     [EventHandler(Order = 1)]
  14.     public void ReceiveAutoDeleteProductMessage(DeleteProductMessage message)
  15.     {
  16.         AddLog($"收到消息({message}”");
  17.     }
  18.     [EventHandler(Order = 2)]
  19.     public void ReceiveAutoCreateProductMessage2(CreateProductMessage message)
  20.     {
  21.         AddLog($"收到消息2({message}”");
  22.     }
  23.     private void AddLog(string message)
  24.     {
  25.         Console.WriteLine($"{timeService.GetTime()}: {message}\r\n");
  26.     }
  27. }
  28. public interface ITimeService
  29. {
  30.     string GetTime();
  31. }
  32. public class TimeService : ITimeService
  33. {
  34.     public string GetTime()
  35.     {
  36.         return DateTime.Now.ToString("HH:mm:ss fff");
  37.     }
  38. }
复制代码
在Program中注册事件总线:
  1. using CodeWF.AspNetCore.EventBus;
  2. var builder = WebApplication.CreateBuilder(args);
  3. builder.Services.AddControllers();
  4. builder.Services.AddEndpointsApiExplorer();
  5. builder.Services.AddSwaggerGen();
  6. // 用于测试事件处理类正常使用IOC功能
  7. builder.Services.AddSingleton<ITimeService, TimeService>();
  8. // 1、注册事件总线,将标注`EventHandler`特性方法的类采用单例方式注入IOC容器
  9. builder.Services.AddEventBus();
  10. var app = builder.Build();
  11. // Configure the HTTP request pipeline.
  12. if (app.Environment.IsDevelopment())
  13. {
  14.     app.UseSwagger();
  15.     app.UseSwaggerUI();
  16. }
  17. app.UseAuthorization();
  18. app.MapControllers();
  19. // 2、将上面已经注入IOC容器的类取出、关联处理方法到事件总线管理
  20. app.UseEventBus();
  21. app.Run();
复制代码
在控制器或其他服务可以发布消息,上面的处理程序会接收处理:
  1. [ApiController]
  2. [Route("[controller]")]
  3. public class EventController : ControllerBase
  4. {
  5.     private readonly ILogger<EventController> _logger;
  6.     private readonly IMessenger _messenger;
  7.     public EventController(ILogger<EventController> logger, IMessenger messenger)
  8.     {
  9.         _logger = logger;
  10.         _messenger = messenger;
  11.     }
  12.     [HttpPost]
  13.     public void Add()
  14.     {
  15.         _messenger.Publish(this, new CreateProductMessage(this, $"{DateTime.Now:HHmmss}号产品"));
  16.     }
  17.     [HttpDelete]
  18.     public void Delete()
  19.     {
  20.         _messenger.Publish(this, new DeleteProductMessage(this, $"{DateTime.Now:HHmmss}号"));
  21.     }
  22. }
复制代码
3. 总结

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

来源:https://www.cnblogs.com/lsq6/p/18240479
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具