.net Core 2中沒有繼續沿用以前asp.net中的管道事件,而是開發了一個新的管道(Middleware): 在Startup的Configure方法中用UseMiddleware方法添加到管道中去 如果將_next.Invoke(httpContext)改成Task.CompletedTa ...
.net Core 2中沒有繼續沿用以前asp.net中的管道事件,而是開發了一個新的管道(Middleware):
public class MiddlewareDemo { private readonly RequestDelegate _next; public MiddlewareDemo(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext) { //可以在此處寫一些需要的代碼 return _next.Invoke(httpContext); } }
在Startup的Configure方法中用UseMiddleware方法添加到管道中去
app.UseMiddleware<MiddlewareDemo>();
如果將_next.Invoke(httpContext)改成Task.CompletedTask那麼後續添加的Middleware都不會執行了
public Task Invoke(HttpContext httpContext) { return Task.CompletedTask; //return _next.Invoke(httpContext); }
通過查看UseMiddleware方法源代碼,發現其實際調用的是IApplicationBuilder的Use方法
下麵來模擬構建Middleware(RequestDelegate)管道
方便演示我們就創建控制台項目,新建RequestDelegate委托類
public delegate Task RequestDelegate(Context context);
public class Context { }
class Program { static List<Func<RequestDelegate, RequestDelegate>> list = new List<Func<RequestDelegate, RequestDelegate>>(); static void Main(string[] args) { Use(next => { return context => { Console.WriteLine("111"); return next.Invoke(context); }; }); Use(next => { return context => { Console.WriteLine("222"); return next.Invoke(context); }; }); Use(next => { return context => { Console.WriteLine("333"); return next.Invoke(context); }; }); Build(); Console.Read(); } static void Use(Func<RequestDelegate, RequestDelegate> middleware) { list.Add(middleware); } static void Build() { RequestDelegate endReq = (context) => { Console.WriteLine("end"); return Task.CompletedTask; }; list.Reverse(); //不反轉的話最後添加的會先執行 foreach (var middleware in list) { endReq = middleware.Invoke(endReq); } endReq(new Context()); } }
運行結果:
如果在某一個Use方法中不執行next.Invoke(context),那麼後續使用Use方法添加的都不會執行了,改成如下:
Use(next => { return context => { Console.WriteLine("222"); return Task.CompletedTask; //return next.Invoke(context); }; });
總結:
這樣的一種模式擴展性比較好,比如一個項目中要使用MVC則寫app.UseMvc來添加進去,使用Session,則用app.UseSession()。
Session/Route等都是使用Middleware來實現的