首页 > 代码库 > Orchard学习 02、orchard 路由

Orchard学习 02、orchard 路由

    Orchard对mvc路由重新做了包装,重写了asp.net的路由模块

一、路由模块类图
1、路由 Descriptor
RouteDescriptor是对常规mvc路由的包装类,它的Route属性就是在mvc注册路由中使用的RouteBase类型。在Orchard中注册路由,应该用这种方式
  1. newRouteDescriptor{    Route=newRoute(        "Admin/Blogs/Create",        newRouteValueDictionary{            {"area","Orchard.Blogs"},            {"controller","BlogAdmin"},            {"action","Create"}        },        newRouteValueDictionary(),        newRouteValueDictionary{            {"area","Orchard.Blogs"}        },        newMvcRouteHandler())}
    View Code

     

     

 
2、路由实现
    Orchard的路由实现有2个类组成:HubRoute和ShellRoute类。它们都继承了System.Web.Routing.RouteBase类,要重新实现GetRouteData和GetVirtualPath方法
2.1、HubRoute类中的GetRouteData方法
  1. publicoverrideRouteDataGetRouteData(HttpContextBase httpContext){    var settings = _runningShellTable.Match(httpContext);    if(settings ==null)    returnnull;     //这里获取1个ShellRoute的集合    IList<RouteBase> routes;    if(!_routesByShell.TryGetValue(settings.Name,out routes))    {        returnnull;    }    foreach(var route in routes)    {        RouteData routeData = route.GetRouteData(httpContext);//这里的route是ShellRoute类型        if(routeData !=null)    {        return routeData;    }    }    returnnull;}
    View Code

     

HubRoute类只是1个route的分配器,它的GetRouteData方法只是从1个ShellRoute集合中获取匹配的 ShellRoute,而真正的获取RouteData 实例的是ShellRoute 类中的 GetRouteData方法
 
2.2、ShellRoute中的GetRouteData方法
  1. publicoverrideRouteDataGetRouteData(HttpContextBase httpContext){    // locate appropriate shell settings for request    var settings = _runningShellTable.Match(httpContext);    // only proceed if there was a match, and it was for this client    if(settings ==null|| settings.Name!= _shellSettings.Name)        returnnull;    var effectiveHttpContext = httpContext;    if(_urlPrefix !=null)        effectiveHttpContext =newUrlPrefixAdjustedHttpContext(httpContext, _urlPrefix);    var routeData = http://www.mamicode.com/_route.GetRouteData(effectiveHttpContext);//这里获取的是真正的mvc RouteData    if(routeData =http://www.mamicode.com/=null)        returnnull;    // otherwise wrap handler and return it     routeData.RouteHandler=newRouteHandler(_workContextAccessor, routeData.RouteHandler,SessionState);     routeData.DataTokens["IWorkContextAccessor"]= _workContextAccessor;    if(IsHttpRoute)    {        routeData.Values["IWorkContextAccessor"]= _workContextAccessor;// for WebApi    }    return routeData;}
    View Code

     

3、路由注册
    Orchard的路由注册功能由2个接口定义:IRouteProvider、IRoutePublisher。Orchard提供默认的实现:DefaultRouteProvider和RoutePublisher类
3.1、DefaultRouteProvider类:
  1. publicclassDefaultRouteProvider:IRouteProvider{     //GetRoutes方法中定义了你要使用的所有的路由信息.    publicIEnumerable<RouteDescriptor>GetRoutes()    {        returnnew[]{        newRouteDescriptor{            Priority=-20,            Route=newRoute(                "{controller}/{action}/{id}",                newRouteValueDictionary{                {"controller","home"},                {"action","index"},                {"id",""},            },        newRouteValueDictionary{            {"controller",newHomeOrAccount()}            },            newMvcRouteHandler())            }        };    }    publicvoidGetRoutes(ICollection<RouteDescriptor> routes)    {        foreach(var routeDescriptor inGetRoutes())            routes.Add(routeDescriptor);    }}
    View Code

     

3.2、RoutePublisher类:
  1.  public void Publish(IEnumerable<RouteDescriptor> routes)        {            var routesArray = routes                .OrderByDescending(r => r.Priority)                .ToArray();            // this is not called often, but is intended to surface problems before            // the actual collection is modified            var preloading = new RouteCollection();            foreach (var routeDescriptor in routesArray)            {                // extract the WebApi route implementation                var httpRouteDescriptor = routeDescriptor as HttpRouteDescriptor;                if (httpRouteDescriptor != null)                {                    var httpRouteCollection = new RouteCollection();                    httpRouteCollection.MapHttpRoute(httpRouteDescriptor.Name, httpRouteDescriptor.RouteTemplate, httpRouteDescriptor.Defaults, httpRouteDescriptor.Constraints);                    routeDescriptor.Route = httpRouteCollection.First();                }                preloading.Add(routeDescriptor.Name, routeDescriptor.Route);            }            using (_routeCollection.GetWriteLock())            {                // existing routes are removed while the collection is briefly inaccessable                _routeCollection                    .OfType<HubRoute>()                    .ForEach(x => x.ReleaseShell(_shellSettings));                // new routes are added                foreach (var routeDescriptor in routesArray)                {                    // Loading session state information.                     var defaultSessionState = SessionStateBehavior.Default;                    ExtensionDescriptor extensionDescriptor = null;                    if (routeDescriptor.Route is Route)                    {                        object extensionId;                        var route = routeDescriptor.Route as Route;                        if (route.DataTokens != null && route.DataTokens.TryGetValue("area", out extensionId) ||                           route.Defaults != null && route.Defaults.TryGetValue("area", out extensionId))                        {                            extensionDescriptor = _extensionManager.GetExtension(extensionId.ToString());                        }                    }                    else if (routeDescriptor.Route is IRouteWithArea)                    {                        var route = routeDescriptor.Route as IRouteWithArea;                        extensionDescriptor = _extensionManager.GetExtension(route.Area);                    }                    if (extensionDescriptor != null)                    {                        // if session state is not define explicitly, use the one define for the extension                        if (routeDescriptor.SessionState == SessionStateBehavior.Default)                        {                            Enum.TryParse(extensionDescriptor.SessionState, true /*ignoreCase*/, out defaultSessionState);                        }                    }                    // Route-level setting overrides module-level setting (from manifest).                    var sessionStateBehavior = routeDescriptor.SessionState == SessionStateBehavior.Default ? defaultSessionState : routeDescriptor.SessionState;                    var shellRoute = new ShellRoute(routeDescriptor.Route, _shellSettings, _workContextAccessor, _runningShellTable)                    {                        IsHttpRoute = routeDescriptor is HttpRouteDescriptor,                        SessionState = sessionStateBehavior                    };                    var area = extensionDescriptor == null ? "" : extensionDescriptor.Id;                    var matchedHubRoute = _routeCollection.FirstOrDefault(x =>                    {                        var hubRoute = x as HubRoute;                        if (hubRoute == null)                        {                            return false;                        }                        return routeDescriptor.Priority == hubRoute.Priority && hubRoute.Area.Equals(area, StringComparison.OrdinalIgnoreCase) && hubRoute.Name == routeDescriptor.Name;                    }) as HubRoute;                    if (matchedHubRoute == null)                    {                        matchedHubRoute = new HubRoute(routeDescriptor.Name, area, routeDescriptor.Priority, _runningShellTable);                        int index;                        for (index = 0; index < _routeCollection.Count; index++)                        {                            var hubRoute = _routeCollection[index] as HubRoute;                            if (hubRoute == null)                            {                                continue;                            }                            if (hubRoute.Priority < matchedHubRoute.Priority)                            {                                break;                            }                        }                        _routeCollection.Insert(index, matchedHubRoute);                    }                    matchedHubRoute.Add(shellRoute, _shellSettings);                }            }        }
    View Code

     

Publish方法将路由注册到asp.net mvc 的路由系统中。
 
二、如何在Module开发中使用路由系统
    Orchard的功能都是通过Module实现的。那么在Module开发中如何使用 路由呢?我们以Orcahrd自己的 Orchard.Blogs Module为例,在Orchard中实现自己的路由其实很简单,只需要在自己的Module中创建1个实现IRouteProvider接口的类型即可。
  1.  public class Routes : IRouteProvider    {        private readonly IArchiveConstraint _archiveConstraint;        private readonly IRsdConstraint _rsdConstraint;        public Routes(            IArchiveConstraint archiveConstraint,            IRsdConstraint rsdConstraint)        {            _archiveConstraint = archiveConstraint;            _rsdConstraint = rsdConstraint;        }        public void GetRoutes(ICollection<RouteDescriptor> routes)        {            foreach (var routeDescriptor in GetRoutes())                routes.Add(routeDescriptor);        }        public IEnumerable<RouteDescriptor> GetRoutes()        {            return new[] {                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/Create",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogAdmin"},                                                                                      {"action", "Create"}                                                                                  },                                                         new RouteValueDictionary(),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/{blogId}/Edit",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogAdmin"},                                                                                      {"action", "Edit"}                                                                                  },                                                         new RouteValueDictionary (),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/{blogId}/Remove",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogAdmin"},                                                                                      {"action", "Remove"}                                                                                  },                                                         new RouteValueDictionary (),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/{blogId}",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogAdmin"},                                                                                      {"action", "Item"}                                                                                  },                                                         new RouteValueDictionary (),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/{blogId}/Posts/Create",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogPostAdmin"},                                                                                      {"action", "Create"}                                                                                  },                                                         new RouteValueDictionary (),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/{blogId}/Posts/{postId}/Edit",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogPostAdmin"},                                                                                      {"action", "Edit"}                                                                                  },                                                         new RouteValueDictionary (),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/{blogId}/Posts/{postId}/Delete",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogPostAdmin"},                                                                                      {"action", "Delete"}                                                                                  },                                                         new RouteValueDictionary (),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/{blogId}/Posts/{postId}/Publish",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogPostAdmin"},                                                                                      {"action", "Publish"}                                                                                  },                                                         new RouteValueDictionary (),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs/{blogId}/Posts/{postId}/Unpublish",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogPostAdmin"},                                                                                      {"action", "Unpublish"}                                                                                  },                                                         new RouteValueDictionary (),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Admin/Blogs",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogAdmin"},                                                                                      {"action", "List"}                                                                                  },                                                         new RouteValueDictionary(),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "Blogs",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "Blog"},                                                                                      {"action", "List"}                                                                                  },                                                         new RouteValueDictionary(),                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Route = new Route(                                                         "{*path}",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "BlogPost"},                                                                                      {"action", "ListByArchive"}                                                                                  },                                                         new RouteValueDictionary {                                                                                      {"path", _archiveConstraint},                                                                                  },                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 },                             new RouteDescriptor {                                                     Priority = 11,                                                     Route = new Route(                                                         "{*path}",                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"},                                                                                      {"controller", "RemoteBlogPublishing"},                                                                                      {"action", "Rsd"}                                                                                  },                                                         new RouteValueDictionary {                                                                                      {"path", _rsdConstraint}                                                                                  },                                                         new RouteValueDictionary {                                                                                      {"area", "Orchard.Blogs"}                                                                                  },                                                         new MvcRouteHandler())                                                 }                         };        }    }
    View Code

     

三、Orchard路由系统如何工作的。
1、将自定义路由注册到asp.net mvc路由系统中
        这个工作是在创建和激活shell的时候,调用 DefaultOrchardShell类的Activate方法时进行的
  1. publicvoidActivate(){    var allRoutes =newList<RouteDescriptor>();     allRoutes.AddRange(_routeProviders.SelectMany(provider => provider.GetRoutes()));     allRoutes.AddRange(_httpRouteProviders.SelectMany(provider => provider.GetRoutes()));     _routePublisher.Publish(allRoutes);//这里就是注册路由    _modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders()));     using (var events = _eventsFactory())    {        events.Value.Activated();    }     _sweepGenerator.Activate();}
    View Code

     

2、路由的使用:像mvc路由一样使用自定义路由。
 



来自为知笔记(Wiz)



Orchard学习 02、orchard 路由