• 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

     

  • 相关阅读:
    代码编辑
    作业7
    实验 13 综合练习三
    模版 实验二 概要设计
    在线评测系统(OJ)使用方法
    作业 6 结构体
    结构体简介
    实验 10 指针2
    (第一周)软件工程四人组
    (第一周)读《构建之法》
  • 原文地址:https://www.cnblogs.com/gangtianci/p/4688112.html
Copyright © 2020-2023  润新知