ABP之模块
ABP的反射
为什么先讲反射,因为ABP的模块管理基本就是对所有程序集进行遍历,再筛选出AbpModule的派生类,再按照以来关系顺序加载。
ABP对反射的封装着重于程序集(Assembly)与类(Type)。系统中分别定义了IAssemblyFinder与ITypeFinder两个接口,从命名上就可以看出这两个接口主要是用来进行程序集与类查找的。
IAssemblyFinder只提供了一个方法 GetAllAssemblies(),从IAssemblyFinder的实现类CurrentDomainAssemblyFinder可以看出这个方法的功能是获取当前应用程序域下所有的程序集。
public class CurrentDomainAssemblyFinder : IAssemblyFinder
{
/// <summary>
/// Gets Singleton instance of <see cref="CurrentDomainAssemblyFinder"/>.
/// </summary>
public static CurrentDomainAssemblyFinder Instance { get { return SingletonInstance; } }
private static readonly CurrentDomainAssemblyFinder SingletonInstance = new CurrentDomainAssemblyFinder(); public List<Assembly> GetAllAssemblies()
{
return AppDomain.CurrentDomain.GetAssemblies().ToList();
}
}
ITypeFinder接口提供了两个方法Find,FindAll,这两个方法的查找范围都是所有当前应用程序域下所有的程序集。ABP为ITypeFinder提供了默认的实现类ITypeFinder,这个类中有个private方法GetAllTypes与一IAssemblyFinder的字段AssemblyFinder。Find,FindAll方法都是都是对GetAllTypes返回结果进行再筛选。
public Type[] Find(Func<Type, bool> predicate)
{
return GetAllTypes().Where(predicate).ToArray();
} public Type[] FindAll()
{
return GetAllTypes().ToArray();
} private List<Type> GetAllTypes()
{
var allTypes = new List<Type>(); foreach (var assembly in AssemblyFinder.GetAllAssemblies().Distinct())
{
try
{
Type[] typesInThisAssembly; try
{
typesInThisAssembly = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
typesInThisAssembly = ex.Types;
} if (typesInThisAssembly.IsNullOrEmpty())
{
continue;
} allTypes.AddRange(typesInThisAssembly.Where(type => type != null));
}
catch (Exception ex)
{
Logger.Warn(ex.ToString(), ex);
}
} return allTypes;
}
主角AbpModule
AbpModule是一抽象类,所有的模块都是他的派生类。AbpModule提供PreInitialize,Initialize,PostInitialize,Shutdown四个无参无返回值方法,从名字上就可以看出AbpModule的生命周期被划成四部分,其中初始化被分成了三部分。
两属性
protected internal IIocManager IocManager { get; internal set; }
protected internal IAbpStartupConfiguration Configuration { get; internal set; }
这两个属性的set方法都不是对程序集外公开的,所以可以判断这两个属性都是ABP系统自身赋值的。再看IocManager,对于这一系统核心依赖注入容器管理者,应该只有一个,所以它应该就是对IoCManager.Instance的引用(这一部分后面会具体体现)。
对于Configuration属性,因还没具体看Configuration部分,所以暂时不细说。但从名字看,它应该是给AbpModule提供一些配置信息。
模块依赖
当一模块的初始化需要其他的模块时,就需要指定它的依赖模块。 在ABP中定义了DependsOnAttribute来出来模块间的依赖关系。
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class DependsOnAttribute : Attribute
{
/// <summary>
/// Types of depended modules.
/// </summary>
public Type[] DependedModuleTypes { get; private set; } /// <summary>
/// Used to define dependencies of an ABP module to other modules.
/// </summary>
/// <param name="dependedModuleTypes">Types of depended modules</param>
public DependsOnAttribute(params Type[] dependedModuleTypes)
{
DependedModuleTypes = dependedModuleTypes;
}
}
DependsOnAttribute只提供了一Type数组属性DependedModuleTypes,用来指定当前模块的依赖AbpModule。依赖模块也是AbpModule类型的,不知ABP为什么没做类型判断。
AbpModuleInfo与AbpModuleCollection
AbpModuleInfo就对模块的抽象,而AbpModuleCollection是AbpModuleInfo的集合,存储系统所有的模块信息。其中AbpModuleCollection提供GetSortedModuleListByDependency方法,这个方法的主要作用就是获取按依赖关系排序后的AbpModuleInfo集合。排序的具体实现间ListExtensions。
ModuleFinder
IModuleFinder及其实现类DefaultModuleFinder,主要是查账应用程序域中所有的模块类(即AbpModule的非抽象派生类)。
AbpModuleManager
AbpModuleManager的主要功能是查找应用程序域下所有AbpModule,再对模块进行实例化,初始化,以及销毁。
AbpModuleManager提供了InitializeModules与ShutdownModules来管理所有模块的生命周期。
ABP对模块的初始化的规范
对于这一部分我就直接引用阳铭的文章了。http://www.cnblogs.com/mienreal/p/4537522.html
ABP的入口
IoCManager与AbpModuleManager分别是依赖注入与系统模块的管理者,那么是什么驱动这两个系统核心。在翻看源代码中,都把矛头指向了AbpBootstrapper。
public class AbpBootstrapper : IDisposable
{
/// <summary>
/// Gets IIocManager object used by this class.
/// </summary>
public IIocManager IocManager { get; private set; } /// <summary>
/// Is this object disposed before?
/// </summary>
protected bool IsDisposed; private IAbpModuleManager _moduleManager; /// <summary>
/// Creates a new <see cref="AbpBootstrapper"/> instance.
/// </summary>
public AbpBootstrapper()
: this(Dependency.IocManager.Instance)
{ } /// <summary>
/// Creates a new <see cref="AbpBootstrapper"/> instance.
/// </summary>
/// <param name="iocManager">IIocManager that is used to bootstrap the ABP system</param>
public AbpBootstrapper(IIocManager iocManager)
{
IocManager = iocManager;
} /// <summary>
/// Initializes the ABP system.
/// </summary>
public virtual void Initialize()
{
IocManager.IocContainer.Install(new AbpCoreInstaller()); IocManager.Resolve<AbpStartupConfiguration>().Initialize(); _moduleManager = IocManager.Resolve<IAbpModuleManager>();
_moduleManager.InitializeModules();
} /// <summary>
/// Disposes the ABP system.
/// </summary>
public virtual void Dispose()
{
if (IsDisposed)
{
return;
} IsDisposed = true; if (_moduleManager != null)
{
_moduleManager.ShutdownModules();
}
}
}
因为AbpBootstrapper实现了IDisposable,所以AbpBootstrapper自身只提供吧 Initialize方法对系统进行初始化,再实现的Dispose方法下对系统进行关闭。
在ABP中提供了自己的HttpApplication派生类AbpWebApplication。其中有一AbpBootstrapper的属性,再AbpWebApplication构造函数中直接实例化AbpWebApplication,在Application对AbpBootstrapper进行初始化,在Application_End对AbpBootstrapper进行Shutdown。
protected AbpBootstrapper AbpBootstrapper { get; private set; } protected AbpWebApplication()
{
AbpBootstrapper = new AbpBootstrapper();
} /// <summary>
/// This method is called by ASP.NET system on web application's startup.
/// </summary>
protected virtual void Application_Start(object sender, EventArgs e)
{
AbpBootstrapper.IocManager.RegisterIfNot<IAssemblyFinder, WebAssemblyFinder>();
AbpBootstrapper.Initialize();
} protected virtual void Application_End(object sender, EventArgs e)
{
AbpBootstrapper.Dispose();
}
ABP之模块的更多相关文章
- 精简ABP的模块依赖
ABP的模块非常方便我们扩展自己的或使用ABP提供的模块功能,对于ABP自身提供的模块间的依赖关系想一探究竟,并且试着把不必要的模块拆掉,找到那部分核心模块.本次使用的是AspNetBoilerpla ...
- Abp 审计模块源码解读
Abp 审计模块源码解读 Abp 框架为我们自带了审计日志功能,审计日志可以方便地查看每次请求接口所耗的时间,能够帮助我们快速定位到某些性能有问题的接口.除此之外,审计日志信息还包含有每次调用接口时客 ...
- ABP框架 - 模块系统
文档目录 本节内容: 简介 模块定义 生命周期方法 PreInitialize(预初始化) Initialize(初始化) PostInitialize(提交初始化) Shutdown(关闭) 模块依 ...
- ABP之模块分析
本篇作为我ABP介绍的第三篇文章,这次想讲下模块的,ABP文档已经有模块这方面的介绍,但是它只讲到如何使用模块,我想详细讲解下它模块的设计思路. ABP 框架提供了创建和组装模块的基础,一个模块能够依 ...
- ABP之模块系统
简介 ASP.NET Boilerplate提供了构建模块的基础结构,并将它们组合在一起以创建应用程序. 模块可以依赖于另一个模块. 通常,一个程序集被视为一个模块. 如果创建具有多个程序集的应用程序 ...
- ABP中模块初始化过程(二)
在上一篇介绍在StartUp类中的ConfigureService()中的AddAbp方法后我们再来重点说一说在Configure()方法中的UserAbp()方法,还是和前面的一样我们来通过代码来进 ...
- ABP新增模块可能遇到的问题
当我们新增一个模块时: public class SSORedisModule: AbpModule { //public override void PreInitialize() //{ // b ...
- Abp 中 模块 加载及类型自动注入 源码学习笔记
注意 互相关联多使用接口注册,所以可以 根据需要替换. 始于 Startup.cs 中的 通过 AddApplication 扩展方法添加 Abp支持 1 services.AddApplicati ...
- ABP配置模块扩展
1.定义一个接口 里面是配置的属性等 public interface IMyConfiguration { int Id { get; set; } string Name { get; set; ...
随机推荐
- Spark的持久化简记
摘要: 1.spark 提供的持久化方法 2.Spark的持久化级别 3.如何选择一种最合适的持久化策略 内容: 1.spark 提供的持久化方法 如果要对一个RDD进行持久化,只要对这个RDD调用c ...
- Java学习笔记(03)
一.回顾运算符: 一.控制语句 1.1 顺序结构 (最常见的) 特点:代码从上往下依次执行
- HTML的页面IE注释
我们常常会在网页的HTML里面看到形如[if lte IE 9]……[endif]的代码,表示的是限定某些浏览器版本才能执行的语句,那么这些判断语句的规则是什么呢?请看下文: <!--[if ! ...
- xcode常见错误处理
问题:xcode 7编译错误:bitcode is not supported on versions of iOS prior to 6.0 解决:Build Options | Enable Bi ...
- NodeJS POST Request Over JSON-RPC
1.npm install art-template2.npm install request3.在app.js中加入以下代码转html: var template = require('art-t ...
- AngularJS之指令中controller与link(十二)
前言 在指令中存在controller和link属性,对这二者心生有点疑问,于是找了资料学习下. 话题 首先我们来看看代码再来分析分析. 第一次尝试 页面: <custom-directive& ...
- JSON入门指南--客户端处理JSON
在传统的Web开发过程中,前端工程师或者后台工程师会在页面上写后台的相关代码,比如在ASP.NET MVC4里面写如下代码: @Html.TextBoxFor(m => m.UserName, ...
- T-SQL:毕业生出门需知系列(三)
第3课 排序检索数据 3.1 排序数据(ORDER BY) 下面的 SQL 语句返回某个数据库表的单个列.观察其输出,并没有特定的顺序. SELECT prod_name FROM Products; ...
- MAT使用--转
原文地址: [1]http://ju.outofmemory.cn/entry/172684 [2]http://ju.outofmemory.cn/entry/129445 MAT使用入门 MAT简 ...
- C#: 向Word插入排版精良的Text Box
Text Box(文本框)是Word排版的工具之一.在Word文档正文的任何地方插入文本框,可添加补充信息,放在合适的位置,也不会影响正文的连续性.我们可以设置文本框的大小,线型,内部边距,背景填充等 ...