探索RegisterAllAreas
2018-06-22 06:00:52来源:未知 阅读 ()
在MVC中注册Area时,我们一般会在相应的区域下定义一个继承与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 { action = "Index", id = UrlParameter.Optional } ); } }
那么问题来了,类AdminAreaRegistration是在什么时候被实例化的,方法RegisterArea是何时被调用的?
1、Global中注册所有区域
AreaRegistration.RegisterAllAreas();
2、查看AreaRegistration.RegisterAllAreas源码
internal static void RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, object state) { //从缓存以及组件中查找所有的AreaRegistration List<Type> filteredTypesFromAssemblies = TypeCacheUtil.GetFilteredTypesFromAssemblies("MVC-AreaRegistrationTypeCache.xml", new Predicate<Type>(AreaRegistration.IsAreaRegistrationType), buildManager); foreach (Type current in filteredTypesFromAssemblies) { AreaRegistration areaRegistration = (AreaRegistration)Activator.CreateInstance(current); areaRegistration.CreateContextAndRegister(routes, state); } }
3、从缓存及引用程序集中查找Type
public static List<Type> GetFilteredTypesFromAssemblies(string cacheName, Predicate<Type> predicate, IBuildManager buildManager) { TypeCacheSerializer serializer = new TypeCacheSerializer(); //从缓存中查找AreaRegistration List<Type> list = TypeCacheUtil.ReadTypesFromCache(cacheName, predicate, buildManager, serializer); if (list != null) { return list; } //从组件中查找AreaRegistration list = TypeCacheUtil.FilterTypesInAssemblies(buildManager, predicate).ToList<Type>(); //添加缓存 TypeCacheUtil.SaveTypesToCache(cacheName, list, buildManager, serializer); return list; }
4、从程序集中查找Type
private static IEnumerable<Type> FilterTypesInAssemblies(IBuildManager buildManager, Predicate<Type> predicate) { IEnumerable<Type> enumerable = Type.EmptyTypes; //获取所有被引用的组件 ICollection referencedAssemblies = buildManager.GetReferencedAssemblies(); foreach (Assembly assembly in referencedAssemblies) { Type[] types; try { //获取组件中的所有类型 types = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } enumerable = enumerable.Concat(types); } //返回所有类型中的AreaRegistration return from type in enumerable where TypeCacheUtil.TypeIsPublicClass(type) && predicate(type) select type; }
5、此处使用predicate(type),不得不回到步骤2看看传入的是啥
private static bool IsAreaRegistrationType(Type type) { return typeof(AreaRegistration).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null; }
6、此时已找到所有的AreaRegistration类,再次回到步骤2,创建AreaRegistration实例,并调用方法RegisterArea
internal void CreateContextAndRegister(RouteCollection routes, object state) { AreaRegistrationContext areaRegistrationContext = new AreaRegistrationContext(this.AreaName, routes, state); string @namespace = base.GetType().Namespace; if (@namespace != null) { areaRegistrationContext.Namespaces.Add(@namespace + ".*"); } this.RegisterArea(areaRegistrationContext); }
由以上代码可以看书,方法RegisterAllAreas就是简单粗暴的将所有引用程序集中的类型遍历一遍,找到所有的AreaRegistration,并调用注册区域方法。
为了验证以上观点,特做了以下测试。
新建一个类库程序,并在类库程序中注册区域,观察是否注册成功。文件结构如下
测试结果:
由于本人也是最近才接触MVC,在学习过程中碰到一些问题,特此备注
1、Mvc定义区域外层文件夹约定为Areas
2、Views文件夹下一定要有web.config,否则会报错(当前上下文中不存在名称“ViewBag”),可以复制项目Views下自动生成的Web.config
3、注册区域可以在其他被引用的项目中(AreaRegistration)
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:自学asp.net mvc(二)
- Asp.net MVC SignalR来做实时Web聊天实例代码 2020-03-29
- ASP.NET MVC中jQuery与angularjs混合应用传参并绑定数据 2020-03-29
- ASP.NET MVC Admin主页快速构建 2020-03-23
- Asp.Net MVC4通过id更新表单内容的思路详解 2020-03-19
- MVC数据验证详解 2020-03-14
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash