看一下继承关系:
public class RouteCollection : IRouteCollection{}
public interface IRouteCollection : IRouter
{
void Add(IRouter router);
}
public interface IRouter
{
// 这里最终的目的是执行Controller 中的Action 方法 返回 输出结果
Task RouteAsync(RouteContext context);
// 返回生成的URL
string GetVirtualPath(VirtualPathContext context);
}
RouteCollection 是一个IRouter 的集合。
结合上一节的TemplateRoute
public class TemplateRoute : INamedRouter{}
public interface INamedRouter : IRouter
{
string Name { get; }
}
可以这么理解:RouteCollection 就是一个 TemplateRoute 的集合。
TemplateRoute 利用 RouteTemplate 和其它的条件 如 请求路径 和 VirtualPathContext 可以路由 可以生成URL。
路由的目的是找到具体的 Controller 和 Action 并执行。
生成URL的目的是 将特定的方法 生成URL 来继续请求。
核心方法有三个:1 Add 添加路由 分为 有名字的 和 无名字的。
public void Add([NotNull] IRouter router)
{
var namedRouter = router as INamedRouter;
if (namedRouter != null)
{
if (!string.IsNullOrEmpty(namedRouter.Name))
{
_namedRoutes.Add(namedRouter.Name, namedRouter);
}
}
else
{
_unnamedRoutes.Add(router);
}
_routes.Add(router);
}
其它两个方法代码:
public async virtual Task RouteAsync(RouteContext context)
{
/*
参数 RouteContext 怎么来的?
新创建一个 然后把 RouteCollection 添加进去
var context = new RouteContext(httpContext);
context.RouteData.Routers.Add(_router);
*/
EnsureLogger(context.HttpContext);
using (_logger.BeginScope("RouteCollection.RouteAsync"))
{
for (var i = 0; i < Count; i++)
{
var route = this[i];
// old 包含所有的 TemplateRoute
var oldRouteData = context.RouteData;
var newRouteData = new RouteData(oldRouteData);
// 取出一个 TemplateRoute
newRouteData.Routers.Add(route);
try
{
context.RouteData = newRouteData;
//这时候 只有一个 TemplateRoute
await route.RouteAsync(context);
if (context.IsHandled)
{
break;
}
}
finally
{
if (!context.IsHandled)
{
context.RouteData = oldRouteData;
}
}
}
if (_logger.IsEnabled(LogLevel.Verbose))
{
_logger.WriteValues(new RouteCollectionRouteAsyncValues()
{
Handled = context.IsHandled,
Routes = _routes
});
}
}
}
public virtual string GetVirtualPath(VirtualPathContext context)
{
if (!string.IsNullOrEmpty(context.RouteName))
{
#region ----context.RouteName 按照已经命名的路由来生成 URL-------
INamedRouter matchedNamedRoute;
_namedRoutes.TryGetValue(context.RouteName, out matchedNamedRoute);
var virtualPath = matchedNamedRoute != null ? matchedNamedRoute.GetVirtualPath(context) : null;
foreach (var unnamedRoute in _unnamedRoutes)
{
var tempVirtualPath = unnamedRoute.GetVirtualPath(context);
if (tempVirtualPath != null)
{
if (virtualPath != null)
{
// 能匹配多个的报错
// There was already a previous route which matched the name.
throw new InvalidOperationException(
Resources.FormatNamedRoutes_AmbiguousRoutesFound(context.RouteName));
}
virtualPath = tempVirtualPath;
}
}
return virtualPath;
#endregion
}
else
{
for (var i = 0; i < Count; i++)
{
var route = this[i];
var path = route.GetVirtualPath(context);
// 找到就返回
if (path != null)
{
return path;
}
}
}
return null;
}
浙公网安备 33010602011771号