zoukankan      html  css  js  c++  java
  • 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 = _route.GetRouteData(effectiveHttpContext);//这里获取的是真正的mvc RouteData
          if(routeData ==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路由一样使用自定义路由。
     





  • 相关阅读:
    Unity3d vector3.forward和transform.forward的区别!
    UGUI实现摇杆
    UGUI实现拼图游戏
    Unity3d打包发布Android程序
    兼容PC和手机触摸代码
    unity3d中Transform组件变量详解
    运算符重载
    扩展方法
    string.Format格式化输出
    网络编程之Socket的TCP协议实现客户端与客户端之间的通信
  • 原文地址:https://www.cnblogs.com/matchcolor/p/4110564.html
Copyright © 2011-2022 走看看