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之模块的更多相关文章

  1. 精简ABP的模块依赖

    ABP的模块非常方便我们扩展自己的或使用ABP提供的模块功能,对于ABP自身提供的模块间的依赖关系想一探究竟,并且试着把不必要的模块拆掉,找到那部分核心模块.本次使用的是AspNetBoilerpla ...

  2. Abp 审计模块源码解读

    Abp 审计模块源码解读 Abp 框架为我们自带了审计日志功能,审计日志可以方便地查看每次请求接口所耗的时间,能够帮助我们快速定位到某些性能有问题的接口.除此之外,审计日志信息还包含有每次调用接口时客 ...

  3. ABP框架 - 模块系统

    文档目录 本节内容: 简介 模块定义 生命周期方法 PreInitialize(预初始化) Initialize(初始化) PostInitialize(提交初始化) Shutdown(关闭) 模块依 ...

  4. ABP之模块分析

    本篇作为我ABP介绍的第三篇文章,这次想讲下模块的,ABP文档已经有模块这方面的介绍,但是它只讲到如何使用模块,我想详细讲解下它模块的设计思路. ABP 框架提供了创建和组装模块的基础,一个模块能够依 ...

  5. ABP之模块系统

    简介 ASP.NET Boilerplate提供了构建模块的基础结构,并将它们组合在一起以创建应用程序. 模块可以依赖于另一个模块. 通常,一个程序集被视为一个模块. 如果创建具有多个程序集的应用程序 ...

  6. ABP中模块初始化过程(二)

    在上一篇介绍在StartUp类中的ConfigureService()中的AddAbp方法后我们再来重点说一说在Configure()方法中的UserAbp()方法,还是和前面的一样我们来通过代码来进 ...

  7. ABP新增模块可能遇到的问题

    当我们新增一个模块时: public class SSORedisModule: AbpModule { //public override void PreInitialize() //{ // b ...

  8. Abp 中 模块 加载及类型自动注入 源码学习笔记

    注意 互相关联多使用接口注册,所以可以 根据需要替换. 始于 Startup.cs 中的  通过 AddApplication 扩展方法添加 Abp支持 1 services.AddApplicati ...

  9. ABP配置模块扩展

    1.定义一个接口  里面是配置的属性等 public interface IMyConfiguration { int Id { get; set; } string Name { get; set; ...

随机推荐

  1. iOS-----Crash文件分析(一)

    开发程序的过程中不管我们已经如何小心,总是会在不经意间遇到程序闪退.脑补一下当你在一群人面前自信的拿着你的App做功能预演的时候,流畅的操作被无情地Crash打断.联想起老罗在发布Smartisan ...

  2. java反射 之 反射基础

    一.反射 反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...

  3. Android笔记——eclipse快捷键

    查看快捷键定义的地方 Window->Preferences->General->Keys. 编辑相关快捷键 1. [ALT+/] 自动提示方法 此快捷键为用户编辑的好帮手,能为用户 ...

  4. SpringAOP之动态代理

    一.动态代理: 1.在原有的静态代理的基础上进一步的完善,由于静态代理中,重复写了相同的代码使得代码的整体结构显得冗余,而且还不同的核心类还需要有不用的代理类,是写死了的具体的类.所以需要使用动态代理 ...

  5. Android图片缓存之Glide进阶

    前言: 前面学习了Glide的简单使用(Android图片缓存之初识Glide),今天来学习一下Glide稍微复杂一点的使用. 图片缓存相关博客地址: Android图片缓存之Bitmap详解 And ...

  6. [ASP.NET] 如果将缓存“滑动过期时间”设置为1秒会怎样?

    今天编写了一个采用ASP.NET Caching的组件,在为它编写Unit Test的过程中发现了一个有趣的问题,接下来我通过一个简单的实例说明这个问题.我们在一个控制台应用中编写了如下一段程序,这个 ...

  7. 苹果系统安装虚拟机 Mac如何安装虚拟机教程

    1.前言    大家在用 Mac 系统的时候,可能有时难免还是要用到 Windows 系统.在 Mac 上使用 Windows 系统有二种方法.一种是在 Mac上安装双系统,适合要在机器上处理一些大型 ...

  8. (转)对Lucene PhraseQuery的slop的理解

    所谓PhraseQuery,就是通过短语来检索,比如我想查"big car"这个短语,那么如果待匹配的document的指定项里包含了"big car"这个短语 ...

  9. Android动画学习(二)——Tween Animation

    前两天写过一篇Android动画学习的概述,大致的划分了下Android Animation的主要分类,没有看过的同学请移步:Android动画学习(一)——Android动画系统框架简介.今天接着来 ...

  10. EntityFramework 如何查看执行的 SQL 代码?

    在 VS 调试的时候,如果我们项目中使用的是 EntityFramework,查看 SQL 执行代码就不像 ADO.NET 那样直观了,我们需要设置下,可以参考下: How can I log the ...