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();
        }
    }
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

 

主角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;
        }
    }
View Code

 

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();
            }
        }
    }
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

 

原文地址:https://www.cnblogs.com/gangtianci/p/4688112.html