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的實例!
?
轉載于:https://www.cnblogs.com/cainiaoguoshi/p/4150097.html
總結
以上是生活随笔為你收集整理的MVC 支持同名路由,不同命名空间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 提炼游戏引擎系列:开篇介绍
- 下一篇: [转]linq to sql (Grou