CodeWF.EventBus,一款靈活的事件匯流排庫,實現模塊間解耦通信。支持多種.NET項目類型,如WPF、WinForms、ASP.NET Core等。採用簡潔設計,輕鬆實現事件的發佈與訂閱。通過有序的消息處理,確保事件得到妥善處理。簡化您的代碼,提升系統可維護性。 ...
1. CodeWF.EventBus
EventBus(事件匯流排),用於解耦模塊之間的通訊。本庫(CodeWF.EventBus)適用於進程內消息傳遞(無其他外部依賴),與大家普遍使用的MediatR部分類似,但MediatR庫側重於ASP.NET Core設計使用,而本庫也有點點優勢:
- 設計可在各種模板項目使用,如WPF、Winform、AvaloniaUI、ASP.NET Core等,主要參考了Prism.Events設計;
- 參考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方式:
- 非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
包:
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)]
定義消息的執行順序。每個消息都可以匹配多個處理程式。一個類中可以有多個消息處理方法,可以訂閱同一個消息,也可以訂閱不同的消息。
支持消息處理程式的註銷:
- 註銷指定處理程式:
Messenger.Default.Unsubscribe<CreateProductMessage>(this, ReceiveManuCreateProductMessage)
- 註銷指定類的所有處理程式:
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,開發過程中參考不少開源項目,他們是: