在学习 asp.net WebApi 或者asp.net Core 的时候,它们管道的处理模型跟 asp.net MVC/WebForm 的管道模型是不一样的。
asp.net WebApi 或者asp.net Core 他们使用了一种叫做“中间件”的处理模型,相对于传统管道模型,剔除了很多非必要的处理,扩展行增强,根据需求进行各种拓展,有类似装饰器、aop的效果。
然后笔者就想看着这样的一种模型我们是不是也可以设计出来呢,知道今天 才有时间鼓捣一下,实现了一个简单的 模型。代码量很少。
这里是仿 asp.net Core 的中间件写的一个中间件模型。直接给出代码如下:
中间件模型
public class MiddleWare<T>
{
public List<Func<T, Func<Task>, Task>> MiddleWares = null;
public MiddleWare()
{
MiddleWares = new List<Func<T, Func<Task>, Task>>();
}
public void Add(Func<T, Func<Task>, Task> middleWare)
{
MiddleWares.Add(middleWare);
}
public async Task Execute(T t)
{
//列表数据倒序,从最后一个注册的func一层一层往上包
MiddleWares.Reverse();
await MiddleWares[MiddleWares.Count - 1].Invoke(t, Execute(t,-1, MiddleWares.Count - 2, null));
}
private Func<Task> Execute(T t,int index ,int count,Func<Task> func)
{
if(index< count)
{
return Execute(t,++index,count, async () => await MiddleWares[index].Invoke(t, func));
}
return func;
}
}
这个模型就一个类,很简单,就是 接收 func 存到列表,然后倒序对 func包装,最后执行。
测试的代码如下:
class Program
{
static void Main(string[] args)
{
MiddleWare<string> middleWare = new MiddleWare<string>();
middleWare.Add(async (s, next) =>
{
Console.WriteLine("---------------异常处理层");
try
{
await next.Invoke();
}
catch (Exception ex)
{
Console.WriteLine($"----------异常:{ex.Message}\r\n{ex.StackTrace}");
}
Console.WriteLine("---------------异常处理层");
});
middleWare.Add(async (s, next) =>
{
Console.WriteLine("中间件第一层---开始");
await next.Invoke();
Console.WriteLine("中间件第一层---结束");
});
middleWare.Add(async (s, next) =>
{
Console.WriteLine(" 中间件第二层---开始");
await next.Invoke();
Console.WriteLine(" 中间件第二层---结束");
});
middleWare.Add(async (s, next) =>
{
Console.WriteLine(" 中间件第三层---开始");
await next.Invoke();
Console.WriteLine(" 中间件第三层---结束");
});
middleWare.Add(async (s, next) =>
{
await Task.Run(() => { Console.WriteLine(" 中间件第四层---开始"); });
await next.Invoke();
await Task.Run(() => { Console.WriteLine(" 中间件第四层---结束"); });
});
middleWare.Add(async (s, next) =>
{
await Task.Run(() => { Console.WriteLine($"核心部分------输入的内容是:{s}"); });
});
Task.WaitAll(middleWare.Execute("哈哈哈哈哈"));
Console.ReadLine();
}
}
效果如图所示: