详解ASP.NET Core MVC 源码学习:Routing 路由

2019-05-25 21:51:50丽君
GetRequestHandler 方法有两个参数,第一个是 HttpContext,就不多说了,主要是来看一下第二个参数 RouteData

RouteData,封装了当前路由中的数据信息,它包含三个主要属性,分别是 DataTokens, Routers, Values

DataTokens: 是匹配的路径中附带的一些相关属性的键值对字典。

Routers: 是一个 Ilist<IRouter> 列表,说明RouteData 中可能会包含子路由。

Values: 当前路由的路径下包含的键值。

还有一个 RouteValueDictionary, 它是一个集合类,主要是用来存放路由中的一些数据信息的,没有直接使用 IEnumerable<KeyValuePair<string, string>> 这个数据结构是应为它的内部存储转换比较复杂,它的构造函数接收一个 Object 的对象,它会尝试将Object 对象转化为自己可以识别的集合。

IRoutingFeature

我根据这个接口的命名一眼就看出来了这个接口的用途,还记得我在之前博客中讲述Http管道流程中得时候提到过一个叫 工具箱 的东西么,这个 IRoutingFeature 也是其中的一个组成部分。我们看一下它的定义:

public interface IRoutingFeature
{
 RouteData RouteData { get; set; }
}

原来他只是包装了 RouteData,到 HttpContext 中啊。

IRouteConstraint

这个接口我在阅读的时候看了一下注释,原来路由中的参数参数检查主要是靠这个接口来完成的。

我们都知道在我们写一个 Route Url地址表达式的时候,有时候会这样写:Route("/Product/{ProductId:long}") , 在这个表达式中有一个 {ProductId:long} 的参数约束,那么它的主要功能实现就是靠这个接口来完成的。

/// Defines the contract that a class must implement in order to check whether a URL parameter
/// value is valid for a constraint.
public interface IRouteConstraint
{
 bool Match(
  HttpContext httpContext,
  IRouter route,
  string routeKey,
  RouteValueDictionary values,
  RouteDirection routeDirection);
}

Microsoft.AspNetCore.Routing

Microsoft.AspNetCore.Routing 主要是对 Abstractions 的一个主要实现,我们阅读代码的时候可以从它的入口开始阅读。

RoutingServiceCollectionExtensions 是一个扩展ASP.NET Core DI 的一个扩展类,在这个方法中用来进行 ConfigService,Routing 对外暴露了一个 IRoutingBuilder 接口用来让用户添加自己的路由规则,我们来看一下:

public static IApplicationBuilder UseRouter(this IApplicationBuilder builder, Action<IRouteBuilder> action)
{
 //...略
 
 // 构造一个RouterBuilder 提供给action委托宫配置
 var routeBuilder = new RouteBuilder(builder);
 action(routeBuilder);
 
 //调用下面的一个扩展方法,routeBuilder.Build() 见下文
 return builder.UseRouter(routeBuilder.Build());
}

public static IApplicationBuilder UseRouter(this IApplicationBuilder builder, IRouter router)
{
  //...略
  
 return builder.UseMiddleware<RouterMiddleware>(router);
}