MVC 支持同名路由,不同命名空间
? ? ?有時候我們會碰到兩個項目合在一起,那么必然會碰到兩個同名的controller,其實MVC在注冊路由,添加Route的時候可以指定當(dāng)前規(guī)則解析那個命名空間下的所有Controller。
? ? ? 注:Controller的調(diào)用是通過IControllerFactory,反射調(diào)用目標(biāo)Controller,不指定目標(biāo)命名空間,直接從BuildManager.GetReferencedAssemblies();如下。
? ? ??
private static List<Type> controllerTypes = new List<Type>();/// <summary>/// 靜態(tài)構(gòu)造函數(shù)/// </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>/// 創(chuàng)建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規(guī)則,要長度不一致,Default帶有"{controller}/{action}/{id}"一直報錯,以為在正則解析看來,無法區(qū)分兩種路由規(guī)則的區(qū)別,因此當(dāng)“http://localhost:4500/Admin/Home/Index”,系統(tǒng)先調(diào)用default的路由解析。
?
其實有一種更好的的方式:
就是建立所謂的區(qū)域,每一個區(qū)域就是一個獨立的子系統(tǒng),如下圖:
其實最為重要的是用了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();調(diào)用這個方法的時候,當(dāng)前Web應(yīng)用所有直接或間接被引用的程序集會被加載,然后從這些程序集中解析出所有繼承自AreaRegistration的類型并反射出對象,調(diào)用相應(yīng)的RegisterArea。
? ? ??
protected void Application_Start(){AreaRegistration.RegisterAllAreas();WebApiConfig.Register(GlobalConfiguration.Configuration);FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);}? 原理:
? MVC調(diào)用Controller是通過反射程序集中繼承了IController的所有類(默認(rèn)情況下),根據(jù)路由規(guī)則取出ControllerName,并實例化相對應(yīng)的Controller實例,如果出現(xiàn)重名的Controller,會報錯。
因此要指定好對應(yīng)的命名空間,MVC將namespace存在RouteData的DateTokens中
十分直觀的的看到,這樣就給不同的路由規(guī)則,反射相應(yīng)的命名空間下IController的實例!
?
轉(zhuǎn)載于:https://www.cnblogs.com/cainiaoguoshi/p/4150097.html
總結(jié)
以上是生活随笔為你收集整理的MVC 支持同名路由,不同命名空间的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 提炼游戏引擎系列:开篇介绍
- 下一篇: c++的ORM解决方案 -- ODB