C# 链式调用,模仿.Net Core中间件写法
定义 MiddlewareDelegate
public delegate Task MiddlewareDelegate(Func<Task> next, PipelineContext context);
定义上下文类
public class PipelineContext
{
public Dictionary<string, object> Items { get; } = new();
public void Set(string key, object value) => Items[key] = value;
public T Get<T>(string key) => Items.TryGetValue(key, out var value) ? (T)value : default;
}
Pipeline 类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class Pipeline
{
private readonly List<MiddlewareDelegate> _middlewares = new();
public Pipeline Use(MiddlewareDelegate middleware)
{
_middlewares.Add(middleware);
return this;
}
public Func<PipelineContext, Task> Build()
{
Func<Task> finalTask = () =>
{
Console.WriteLine("Pipeline End: Final Task");
return Task.CompletedTask;
};
Func<PipelineContext, Task> pipeline = context => finalTask();
foreach (var middleware in _middlewares.AsReadOnly().Reverse())
{
var next = pipeline;
pipeline = context => middleware(() => next(context), context);
}
return pipeline;
}
}
使用
class Program
{
static async Task Main(string[] args)
{
var pipeline = new Pipeline();
pipeline.Use(async (next, context) =>
{
Console.WriteLine("Middleware 1: Before");
context.Set("Key1", "Value1"); // 设置上下文数据
await next();
Console.WriteLine("Middleware 1: After");
});
pipeline.Use(async (next, context) =>
{
Console.WriteLine("Middleware 2: Before");
var key1Value = context.Get<string>("Key1"); // 读取上下文数据
Console.WriteLine($"Key1 Value: {key1Value}");
context.Set("Key2", "Value2");
await next();
Console.WriteLine("Middleware 2: After");
});
pipeline.Use((next, context) =>
{
Console.WriteLine("Middleware 3: Endpoint");
var key2Value = context.Get<string>("Key2");
Console.WriteLine($"Key2 Value: {key2Value}");
return Task.CompletedTask;
});
var executablePipeline = pipeline.Build();
// 创建上下文并运行管道
var context = new PipelineContext();
await executablePipeline(context);
}
}
输出
Middleware 1: Before
Middleware 2: Before
Key1 Value: Value1
Middleware 3: Endpoint
Key2 Value: Value2
Middleware 2: After
Middleware 1: After
Pipeline End: Final Task