在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. C++ 连接数据库的入口和获取列数、数据

    这里不具体放出完整的程序,分享两个核心函数: 由于这里用到的函数是编译器自己的库所没有的,需要自己下载mysql.h库或者本地有数据库,可以去bin找到,放进去. 前提,我自己的测试数据库是WampS ...

  2. 前端自动化构建工具gulp的使用总结

    前端自动化构建工具gulp的使用总结 博主最近偶的空闲,在此对gulp的使用做一个总结,让小伙伴知道如何合理的使用gulp以及gulp的使用技巧. 谈到gulp,有人可能就会想到另外一个构建工具gru ...

  3. 用纯JS做俄罗斯方块 - 简要思路介绍(1)

    大家都知道俄罗斯方块是一款大众化的游戏了,我很小的时候就玩过,今年已经25岁了,可以说俄罗斯方块确实是历史悠久,做俄罗斯方块是我上个星期开始的想法.也许是由于自己从来没有写过这种东西吧,所以有生疏.代 ...

  4. 通过寄生组合式继承创建js的异常类

    最近项目中在做js的统一的异常处理,需要自定义异常类.理想的设计方案为:自定义一个异常错误类BaseError,继承自Error,然后再自定义若干个系统异常,例如用户取消异常.表单异常.网络异常,这些 ...

  5. APP接口自动化测试JAVA+TestNG(二)之TestNG简介与基础实例

    前言 继上篇环境篇后,本篇主要对TestNG进行介绍,给出最最基础的两个实例,通过本文后,学会并掌握TestNG测试用例的编写与运行,以及生成美化后的报告.下一篇为HTTP接口实战(国家气象局接口自动 ...

  6. css3+visbibilty解决淡入淡出问题

    .fade{ visibility: hidden; opacity: ; transition: all .5s; } .fade.on { visibility: visible; opacity ...

  7. log4net的使用

    1.0 下载并引用 log4net.dll 2.0 修改Web.config <configuration> <configSections> <section name ...

  8. C#使用Log4Net记录日志

    当你在开发程序的时候, 调试(debugging)和日志(logging)都是非常重要的工作.在应用中使用日志主要有三个目的 l  监视代码中的变量的变化情况,把数据周期性地记录到文件中供其它应用进行 ...

  9. MySQL使用if判断

    select *,if(sva=1,"男","女") as ssva from taname where sva<>"" 12. ...

  10. [moka同学笔记]七、Yii2.0课程笔记(魏曦老师教程)[新增管理员,重置密码]