在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)

探索RegisterAllAreas的更多相关文章

  1. .net EntityFramework用法探索系列 1

    EntityFramework用法探索系列 (一)DatabaseFirst (二)CodeFirst (三)CodeFirst流畅API (四)Repository和UnitOfWork (五)引入 ...

  2. 【探索】机器指令翻译成 JavaScript

    前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念.为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学. 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript ...

  3. 【探索】利用 canvas 实现数据压缩

    前言 HTTP 支持 GZip 压缩,可节省不少传输资源.但遗憾的是,只有下载才有,上传并不支持.如果上传也能压缩,那就完美了.特别适合大量文本提交的场合,比如博客园,就是很好的例子. 虽然标准不支持 ...

  4. 探索C#之6.0语法糖剖析

    阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...

  5. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  6. Linux学习之探索文件系统

    Linux,一起学习进步-    ls With it, we can see directory contents and determine a variety of important file ...

  7. 马里奥AI实现方式探索 ——神经网络+增强学习

    [TOC] 马里奥AI实现方式探索 --神经网络+增强学习 儿时我们都曾有过一个经典游戏的体验,就是马里奥(顶蘑菇^v^),这次里约奥运会闭幕式,日本作为2020年东京奥运会的东道主,安倍最后也已经典 ...

  8. C++随笔:.NET CoreCLR之GC探索(4)

    今天继续来 带大家讲解CoreCLR之GC,首先我们继续看这个GCSample,这篇文章是上一篇文章的继续,如果有不清楚的,还请翻到我写的上一篇随笔.下面我们继续: // Initialize fre ...

  9. C++随笔:.NET CoreCLR之GC探索(2)

    首先谢谢 @dudu 和 @张善友 这2位大神能订阅我,本来在写这个系列以前,我一直对写一些核心而且底层的知识持怀疑态度,我为什么持怀疑态度呢?因为一般写高层语言的人99%都不会碰底层,其实说句实话, ...

随机推荐

  1. 清除inline-block元素之间的空白

    一个元素如果被设置为display:inline-block,那么这个元素将表现为行内块的性质.被设为行内块的元素 对内(子元素)表现为块级框,具体为可以设置高度宽度,可以设置垂直margin和pad ...

  2. html标签属性(attribute)和dom元素的属性(property)

    简介 attribute和property都有属性之意,但对于attribute和property的区分其实并不难.从对象来说,attribute是html文档上标签属性, 而property则是对应 ...

  3. MySQL学习(二)SQL语句的总结

    1.连接查询和关联查询连接查询:把两个表中相同的元素的连接就可以查询,使用:where里,select table1.*,table2.* from table1,table2 where table ...

  4. maven全局配置文件settings.xml详解

    概要 settings.xml有什么用? 如果在Eclipse中使用过Maven插件,想必会有这个经验:配置settings.xml文件的路径. settings.xml文件是干什么的,为什么要配置它 ...

  5. css毛玻璃效果

    毛玻璃其实就是磨砂玻璃,能够模糊的看清背后的风景,让人感觉有种朦胧美,让界面看上去有些层次感. 比如: 高大上啊,接下来肯定是眼馋手痒的过程... 当然,用ps搞一个全景毛玻璃背景毫无疑问是最省事的, ...

  6. C#使用Graphics画圆写字

    画填充圆: Graphics gra = this.pictureBox1.CreateGraphics(); gra.SmoothingMode = System.Drawing.Drawing2D ...

  7. C#正则表达式Regex常用匹配

    使用Regex类需要引用命名空间:using System.Text.RegularExpressions; 利用Regex类实现验证 示例1:注释的代码所起的作用是相同的,不过一个是静态方法,一个是 ...

  8. C标准头文件<string.h>

    里面主要包含了一些与字符串关联的函数的声明,这些函数有如下的命名规则: 以"mem"开头的函数操作任意的字符序列 以"strn"开头的函数操作非空字符序列 以& ...

  9. PHP中抽象类,接口定义

    这里先介绍接口,因为在我最近看的好几本php工具书中都没有提到抽象类. 本人也觉得,在理解了接口后抽象类也非常好理解. 例子代码随便写了一下.例子代码是很ok的,测试过了不会报错,懒得看代码的筒靴们看 ...

  10. java.lang.IllegalArgumentException: Illegal character in query at index 261

    在BaseFragment中使用了LoadingPage,而LoadingPage的联网加载使用的是AsyncHttpClient.一直报java.lang.IllegalArgumentExcept ...