• MVC 支持同名路由,不同命名空间


         有时候我们会碰到两个项目合在一起,那么必然会碰到两个同名的controller,其实MVC在注册路由,添加Route的时候可以指定当前规则解析那个命名空间下的所有Controller。

          注:Controller的调用是通过IControllerFactory,反射调用目标Controller,不指定目标命名空间,直接从BuildManager.GetReferencedAssemblies();如下。

          

      private static List<Type> controllerTypes = new List<Type>();
            /// <summary>
            /// 静态构造函数
            /// </summary>
            static DefaultControllerFactory()
            {
                var assemblys = BuildManager.GetReferencedAssemblies();
                foreach (Assembly assembly in assemblys)
                {
                    var types = assembly.GetTypes().Where(a => typeof(IController).IsAssignableFrom(a));
                    foreach (Type type in types)
                    {
                        controllerTypes.Add(type);
                    }
                }
            }
    
            /// <summary>
            /// 创建controller
            /// </summary>
            /// <param name="requestContext"></param>
            /// <param name="controllerName"></param>
            /// <returns></returns>
            public IController CreateController(RequestContext requestContext, string controllerName)
            {
                string typeName = controllerName + "Controller";
                Type controllerType = controllerTypes.FirstOrDefault(a => a.Name == typeName);
                if (controllerType != null)
                {
                    return (IController)Activator.CreateInstance(controllerType);
                }
                return null;
            }

          回归正题:如何支持多种命名空间

          

     public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}",
                    defaults: new { controller = "Home", action = "Index" }, namespaces: new string[] { "MvcExpose.Controllers" }
                );
                routes.MapRoute("Admin", "Admin/{controller}/{action}",
                    new { controller = "Home", action = "Index"}, new string[] { "MvcExpose.Admin.Controllers" });
            }

            切记:两种注册Url规则,要长度不一致,Default带有"{controller}/{action}/{id}"一直报错,以为在正则解析看来,无法区分两种路由规则的区别,因此当“http://localhost:4500/Admin/Home/Index”,系统先调用default的路由解析。

    其实有一种更好的的方式:

    就是建立所谓的区域,每一个区域就是一个独立的子系统,如下图:

    其实最为重要的是用了AreaRegistration

    public class AdminAreaRegistration : AreaRegistration
        {
            public override string AreaName
            {
                get
                {
                    return "Admin";
                }
            }
    
            public override void RegisterArea(AreaRegistrationContext context)
            {
                context.MapRoute(
                    "Admin_default",
                    "Admin/{controller}/{action}/{id}",
                    new { controller="home",action = "Index", id = UrlParameter.Optional }
                );
            }
        }
    

      在Global中,我们有一句:   AreaRegistration.RegisterAllAreas();调用这个方法的时候,当前Web应用所有直接或间接被引用的程序集会被加载,然后从这些程序集中解析出所有继承自AreaRegistration的类型并反射出对象,调用相应的RegisterArea。

          

     protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
            }

      原理:

      MVC调用Controller是通过反射程序集中继承了IController的所有类(默认情况下),根据路由规则取出ControllerName,并实例化相对应的Controller实例,如果出现重名的Controller,会报错。

    因此要指定好对应的命名空间,MVC将namespace存在RouteData的DateTokens中

    十分直观的的看到,这样就给不同的路由规则,反射相应的命名空间下IController的实例!

  • 相关阅读:
    SCRAM
    package-info.java https://www.intertech.com/Blog/whats-package-info-java-for/
    mybatis-3 cache 源码赏析
    Cache replacement policies 缓存实现算法
    MyBatis 强大之处 多环境 多数据源 ResultMap 的设计思想是 缓存算法 跨数据库 spring boot rest api mybaits limit 传参
    Taking a peek inside with the Actuator
    表优化 altering table OPTIMIZE TABLE `sta_addr_copy`
    Why is long2ip conversion important?
    遇到的1/3,在十进位制中是一个无限小数,但在这种进位制中就是一个有限小数。
    并发编程:Actors 模型和 CSP 模型
  • 原文地址:https://www.cnblogs.com/cainiaoguoshi/p/4150097.html
Copyright © 2020-2023  润新知