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; ...
随机推荐
- WCF服务创建与抛出强类型SOAP Fault
原创地址:http://www.cnblogs.com/jfzhu/p/4060666.html 转载请注明出处 前面的文章<WCF服务的异常消息>中介绍过,如果WCF Service发生 ...
- Ubuntu上安装Robomongo及添加到启动器
到目前为止,Robomongo仍是MongoDB最好的客户端管理工具,如需在Ubuntu上安装Robomongo,可直接从官网下载.tar.gz压缩包进行解压,然后直接运行bin目录下的robomon ...
- JavaScript算法(冒泡排序、选择排序与插入排序)
冒泡排序.选择排序与插入排序复杂度都是二次方级别的,放在一起说吧. 介绍一些学习这三个排序方法的比较好的资料.冒泡排序看<学习JavaScript数据结构与算法>介绍的冒泡排序,选择排序看 ...
- python 栈和队列(使用list实现)
5.1.1. Using Lists as Stacks The list methods make it very easy to use a list as a stack, where the ...
- Atitit 图像处理 深刻理解梯度原理计算.v1 qc8
Atitit 图像处理 深刻理解梯度原理计算.v1 qc8 1.1. 图像处理 梯度计算 基本梯度 内部梯度 外部梯度 方向梯度1 2. 图像梯度就是图像边缘吗?2 1.1. 图像处理 梯度计算 ...
- Oralce 重建EM服务,OracleDBConsoleOracle
今天打开Oracle ,想进em看看,结果发现OracleDBConsoleOracle服务老是报错: OracleDBConsoleOracle 服务因 2 (0x2) 服务性错误而停止. 搞不懂, ...
- Highchart.js
Highcharts所有的源代码及例子均可通过官网下载得到.初学者只需要简单的修改官方提供的例子即可了解Highcharts. 下载 最新版本:Highcharts 3.0.10.Highstock ...
- 让虚拟机的软盘盘符不显示(适用于所有windows系统包括Windows Server)
- OpenCASCADE Root-Finding Algorithm
OpenCASCADE Root-Finding Algorithm eryar@163.com Abstract. A root-finding algorithm is a numerical m ...
- 用bootstrap实现多张图片手动轮回
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABBoAAAJoCAIAAABHhBX4AAAgAElEQVR4nOzdZXdcV7rg8fmIM2vm3r