本文共 3949 字,大约阅读时间需要 13 分钟。
httpContext
实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合IRouter.RouteAsync
方法,该方法主要是进行路由匹配,匹配成功后给context.Handler
赋值namespace Microsoft.AspNetCore.Builder{ public class RouterMiddleware { private readonly ILogger _logger; private readonly RequestDelegate _next; private readonly IRouter _router; public RouterMiddleware( RequestDelegate next, ILoggerFactory loggerFactory, IRouter router) { _next = next; _router = router; _logger = loggerFactory.CreateLogger(); } public async Task Invoke(HttpContext httpContext) { var context = new RouteContext(httpContext); context.RouteData.Routers.Add(_router); await _router.RouteAsync(context); if (context.Handler == null) { _logger.RequestDidNotMatchRoutes(); await _next.Invoke(httpContext); } else { httpContext.Features[typeof(IRoutingFeature)] = new RoutingFeature() { RouteData = context.RouteData, }; await context.Handler(context.HttpContext); } } }}
IRouter
接口仅定义了两个方法,其中路由的核心在于RouteAsync
方法,该方法可用于路由匹配,返回处理委托RouteBase
抽象类的的RouteAsync
方法进行路由的匹配,Route
类的RouteAsync
方法仅仅是执行了构造函数传进来的routeBuilder.DefaultHandler
路由的RouteAsync
方法,DefaultHandler
实际上也是继承自IRouter
RouteHandler
和MvcRouteHandler
都可以作为routeBuilder.DefaultHandler
,以提供Route
类实例化需要的参数。RouteHandler
的RouteAsync
方法直接给context.Handler
赋值从构造函数接收到的委托。MvcRouteHandler``RouteAsync
方法则先根据匹配到的路由从已注册的控制器中适配方法,然后得到actionDescriptor
,包含http上下文以及方法的基本信息,最后直接给context.Handler
赋值,MVC流程从invoker.InvokeAsync()
开始public Task RouteAsync(RouteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var candidates = _actionSelector.SelectCandidates(context); if (candidates == null || candidates.Count == 0) { _logger.NoActionsMatched(context.RouteData.Values); return Task.CompletedTask; } var actionDescriptor = _actionSelector.SelectBestCandidate(context, candidates); if (actionDescriptor == null) { _logger.NoActionsMatched(context.RouteData.Values); return Task.CompletedTask; } context.Handler = (c) => { var routeData = c.GetRouteData(); var actionContext = new ActionContext(context.HttpContext, routeData, actionDescriptor); if (_actionContextAccessor != null) { _actionContextAccessor.ActionContext = actionContext; } var invoker = _actionInvokerFactory.CreateInvoker(actionContext); if (invoker == null) { throw new InvalidOperationException( Resources.FormatActionInvokerFactory_CouldNotCreateInvoker( actionDescriptor.DisplayName)); } return invoker.InvokeAsync(); }; return Task.CompletedTask; }
app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
Handler
用于后续处理消息IRouter
实例的RouteAsync
方法,得到Handler
的话就执行,否则处理权交给下一个中间件。而路由实现,主要是匹配过程以及返回Handler
。到这里,就可以发散思维,做各种有趣的事了转载地址:http://uhdja.baihongyu.com/