中间件/管道模式

管道模式(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("后置日志");
    }
}

  

 

posted @ 2026-08-02 16:04  HelloWorld庄先生  阅读(7)  评论(0)    收藏  举报