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号