为什么先讲反射,因为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(); } }View Code
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; }View Code
A bpModule是一抽象类,所有的模块都是他的派生类。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; } }View Code
DependsOnAttribute只提供了一Type数组属性DependedModuleTypes,用来指定当前模块的依赖AbpModule。依赖模块也是AbpModule类型的,不知ABP为什么没做类型判断。
AbpModuleInfo就对模块的抽象,而AbpModuleCollection是AbpModuleInfo的集合,存储系统所有的模块信息。其中AbpModuleCollection提供GetSortedModuleListByDependency方法,这个方法的主要作用就是获取按依赖关系排序后的AbpModuleInfo集合。排序的具体实现间ListExtensions。
IModuleFinder及其实现类DefaultModuleFinder,主要是查账应用程序域中所有的模块类(即AbpModule的非抽象派生类)。
AbpModuleManager的主要功能是查找应用程序域下所有AbpModule,再对模块进行实例化,初始化,以及销毁。
AbpModuleManager提供了 InitializeModules与ShutdownModules来管理所有模块的生命周期。
对于这一部分我就直接引用阳铭的文章了。 http://www.cnblogs.com/mienreal/p/4537522.html
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(); } } }View Code
因为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(); }View Code