C# 消息分发器模式,开闭原则,类型注解,反射注册,解耦,通信管理
基于消息分发器模式和反射注册,这种设计适合需要灵活扩展消息类型的场景(如通信协议、命令处理系统)。
1. 类关系图(核心设计)
使用类图展示各组件的继承、依赖和关联关系:
classDiagram
direction LR
class MessageTypeAttribute {
+ int Type
+ MessageTypeAttribute(int type)
}
class MessageHandlerBase {
+ abstract Task HandleAsync(string message)
}
class HelloMessageHandler {
+ override Task HandleAsync(string message)
}
class ByeMessageHandler {
+ override Task HandleAsync(string message)
}
class MessageDispatcher {
- Dictionary<int, MessageHandlerBase> _handlers
+ MessageDispatcher()
+ async Task DispatchAsync(int type, string message)
}
class Program {
+ static async Task Main()
}
HelloMessageHandler --|> MessageHandlerBase
ByeMessageHandler --|> MessageHandlerBase
MessageTypeAttribute "1" <|-- "1" HelloMessageHandler : 标记
MessageTypeAttribute "1" <|-- "1" ByeMessageHandler : 标记
MessageDispatcher "1" *-- "*" MessageHandlerBase : 管理
MessageDispatcher "1" --> "1" MessageTypeAttribute : 读取
Program "1" --> "1" MessageDispatcher : 使用
2. 消息处理流程图(补充流程)
用流程图展示消息从分发到处理的完整流程:
flowchart TD
A[Program 调用 DispatchAsync] --> B[MessageDispatcher 检查_handlers字典]
B -->|存在对应type的Handler| C[调用Handler.HandleAsync]
B -->|不存在| D[输出No handler for message type X]
C --> E[HelloMessageHandler/ByeMessageHandler 处理消息]
E --> F[完成处理]
D --> F
设计思路说明
-
核心组件职责:
MessageTypeAttribute:特性类,用于标记处理器对应的消息类型(如[MessageType(1)]绑定到HelloMessageHandler)。MessageHandlerBase:抽象基类,定义消息处理的统一接口HandleAsync。HelloMessageHandler/ByeMessageHandler:具体处理器,继承基类并实现特定类型的消息处理逻辑,重写基类中的方法。MessageDispatcher:分发器核心,通过反射自动注册所有带MessageTypeAttribute的处理器,根据消息类型分发到对应处理器。Program:入口类,创建分发器并发起消息分发。
-
关键设计亮点:
- 反射注册:
MessageDispatcher在构造函数中通过反射扫描程序集,自动发现并注册所有消息处理器,无需手动添加。 - 开闭原则:新增消息类型时,只需创建新的
XXXMessageHandler并标记MessageTypeAttribute,无需修改分发器代码。 - 类型绑定:通过
int类型的消息标识绑定处理器,实现“类型→处理器”的映射。
- 反射注册:
源代码
DispatchDemo\ByeMessageHandler.cs
[MessageType(2)]
public class ByeMessageHandler : MessageHandlerBase
{
public override Task HandleAsync(string message)
{
Console.WriteLine($"Bye handler received: {message}");
return Task.CompletedTask;
}
}
DispatchDemo\DispatchDemo.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
DispatchDemo\HelloMessageHandler.cs
[MessageType(1)]
public class HelloMessageHandler : MessageHandlerBase
{
public override Task HandleAsync(string message)
{
Console.WriteLine($"Hello handler received: {message}");
return Task.CompletedTask;
}
}
DispatchDemo\MessageDispatcher.cs
using System.Reflection;
public class MessageDispatcher
{
private readonly Dictionary<int, MessageHandlerBase> _handlers = new();
public MessageDispatcher()
{
// 反射注册所有带 MessageTypeAttribute 的处理器
var handlerTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.GetCustomAttribute<MessageTypeAttribute>() != null);
foreach (var type in handlerTypes)
{
var attr = type.GetCustomAttribute<MessageTypeAttribute>();
var handler = (MessageHandlerBase)Activator.CreateInstance(type);
_handlers[attr.Type] = handler;
}
}
public async Task DispatchAsync(int type, string message)
{
if (_handlers.TryGetValue(type, out var handler))
{
await handler.HandleAsync(message);
}
else
{
Console.WriteLine("No handler for message type " + type);
}
}
}
DispatchDemo\MessageHandlerBase.cs
public abstract class MessageHandlerBase
{
public abstract Task HandleAsync(string message);
}
DispatchDemo\MessageTypeAttribute.cs
[AttributeUsage(AttributeTargets.Class)]
public class MessageTypeAttribute : Attribute
{
public int Type { get; }
public MessageTypeAttribute(int type) => Type = type;
}
DispatchDemo\Program.cs
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var dispatcher = new MessageDispatcher();
await dispatcher.DispatchAsync(1, "Hello, world!");
await dispatcher.DispatchAsync(2, "Goodbye, world!");
await dispatcher.DispatchAsync(3, "Unknown message");
}
}
浙公网安备 33010602011771号