中间件/管道模式
管道模式(Pipeline Pattern)
把一个任务按照顺序交给一连串处理器依次执行,形成一条流水线。请求从头流入管道,依次经过各个处理器,处理完成后反向回流。
链式结构:请求 → 中间件1 → 中间件2 → 中间件3 → 业务处理 → 原路返回
中间件模式(Middleware)
管道中每一个独立、可插拔、职责单一的组件就是中间件。
可以拦截请求、预处理
可以把请求交给下一个中间件
收到下游返回结果后,做后置处理
支持自由增删、调整顺序、解耦
整体架构
1.Context(上下文):承载本次请求所有数据
2.MiddlewareDelegate:中间件委托
3.PipelineBuilder:管道构造器,祖册,组装中间件
4.各个业务中间件
5.在ViewModel/后台服务调用管道执行
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace WpfMiddlewareDemo
{
/// <summary>
/// 管道上下文:承载一次指令请求全部信息(类比HttpContext)
/// </summary>
public class CommandContext
{
// 输入:设备指令
public string Command { get; set; }
// 是否中断管道(终止后续中间件执行)
public bool IsAbort { get; set; }
// 返回结果
public object Result { get; set; }
// 异常信息
public Exception Exception { get; set; }
}
/// <summary>
/// 中间件委托
/// </summary>
public delegate Task MiddlewareDelegate(CommandContext context);
/// <summary>
/// 管道构建器,用来注册中间件、生成执行管道
/// </summary>
public class CommandPipelineBuilder
{
private readonly List<Func<MiddlewareDelegate, MiddlewareDelegate>> _components = new();
/// <summary>
/// 注册中间件
/// </summary>
public void Use(Func<MiddlewareDelegate, MiddlewareDelegate> middleware)
{
_components.Add(middleware);
}
/// <summary>
/// 构建最终执行管道(反向组装,和AspNetCore原理一致)
/// </summary>
public MiddlewareDelegate Build()
{
// 管道终点:最终执行业务(下发设备)
MiddlewareDelegate endPipe = ctx =>
{
if (!ctx.IsAbort)
{
Console.WriteLine($"【底层执行指令】{ctx.Command}");
ctx.Result = "指令执行成功";
}
return Task.CompletedTask;
};
MiddlewareDelegate pipeline = endPipe;
// 反向链式拼接
for (int i = _components.Count - 1; i >= 0; i--)
{
pipeline = _components[i](pipeline);
}
return pipeline;
}
}
// ============ 使用示例(ViewModel / Service 中调用)============
public class DeviceService
{
private readonly MiddlewareDelegate _pipeline;
public DeviceService()
{
var builder = new CommandPipelineBuilder();
// 中间件1:日志中间件
builder.Use(next => async ctx =>
{
Console.WriteLine($"[日志中间件] 开始处理指令:{ctx.Command}");
await next(ctx);
Console.WriteLine($"[日志中间件] 处理完成,结果:{ctx.Result}");
});
// 中间件2:参数校验中间件
builder.Use(next => async ctx =>
{
if (string.IsNullOrWhiteSpace(ctx.Command))
{
ctx.IsAbort = true;
ctx.Exception = new ArgumentException("指令不能为空!");
Console.WriteLine("[校验中间件] 参数非法,终止管道");
return; // 不执行next,截断后续链路
}
await next(ctx);
});
// 中间件3:权限拦截中间件
builder.Use(next => async ctx =>
{
if (ctx.Command.Contains("EMERGENCY_STOP") == false)
{
Console.WriteLine("[权限中间件] 普通指令放行");
}
await next(ctx);
});
// 生成管道
_pipeline = builder.Build();
}
/// <summary>
/// 对外暴露:发送设备指令入口
/// </summary>
public async Task<CommandContext> SendCommandAsync(string cmd)
{
var context = new CommandContext
{
Command = cmd
};
await _pipeline(context);
return context;
}
}
}
// ViewModel
public class MainViewModel
{
private readonly DeviceService _deviceService = new DeviceService();
public ICommand SendCmdCommand { get; }
public MainViewModel()
{
SendCmdCommand = new RelayCommand(async () =>
{
var ctx = await _deviceService.SendCommandAsync("MOVE_X 100.0");
if (ctx.Exception != null)
{
// UI弹窗提示异常
MessageBox.Show(ctx.Exception.Message);
}
else
{
MessageBox.Show($"返回:{ctx.Result}");
}
});
}
}
封装独立的IMiddleware
public interface IMiddleware
{
Task InvokeAsync(CommandContext context, MiddlewareDelegate next);
}
// 日志中间件类
public class LogMiddleware : IMiddleware
{
public async Task InvokeAsync(CommandContext context, MiddlewareDelegate next)
{
Console.WriteLine("前置日志");
await next(context);
Console.WriteLine("后置日志");
}
}
浙公网安备 33010602011771号