ETJava Beta | Java    注册   登录
  • 搜索:
  • ABP VNext 系列:框架启动流程以及依赖注入原理和源码分析

    发表于      阅读(1)     博客类别:Crawler     转自:https://www.cnblogs.com/vic-tory/p/18467510
    如有侵权 请联系我们删除  (页面底部联系我们)  

    简单介绍 ABP VNext

    Github 地址:https://github.com/abpframework/abp
    官网文档地址:https://abp.io/docs/latest
    官网:https://abp.io/

    • ABP VNext 框架是一个基于 ASP.NET Core 的完整基础架构,也就是我们现在称的 ABP 框架,它遵循软件开发最佳实践和最新技术来创建现代 Web 应用程序和 API。
    • ABP vNext 是 ABP 框架作者所发起的新项目,ABP vNext 框架核心库比 ABP 框架更加精简,因为将原有许多的组件从其核心库抽离成独立的组件。这样开发人员可以更加灵活的选择自己需要的功能进行集成,使项目远离臃肿的库。
    • ABP 提供了基于领域驱动设计原则和模式的完整、模块化和分层的软件架构。它还提供了实现此架构所需的基础架构和指导。
    • ABP 框架提供了许多功能来更轻松地实现实际场景,例如事件总线、后台作业系统、审计日志、BLOB 存储、数据播种、数据过滤等。

    框架启动流程

    模块化文档:https://abp.io/docs/latest/framework/architecture/modularity/basics

    下载源码:https://github.com/abpframework/abp/tree/dev/framework

    image

    参考构建一个新 ASP.NET Core MVC 的项目:https://abp.io/docs/latest/get-started/empty-aspnet-core-application

    image

        public class Program
        {
            public static async Task Main(string[] args)
            {
                var builder = WebApplication.CreateBuilder(args);
                builder.Host.UseAutofac(); //推荐使用Autofac作为依赖注入框架
                //注入ABP相关服务
                await builder.Services.AddApplicationAsync<MCodeAbpWebModule>();
                var app = builder.Build();
                //初始化程序
                await app.InitializeApplicationAsync();
                await app.RunAsync();
            }
        }
    
    
        /// <summary>
        /// 需要什么模块引入什么模块,才会注入
        /// </summary>
        [DependsOn(
             typeof(AbpAspNetCoreMvcModule),
             typeof(AbpSwashbuckleModule),
             typeof(MCodeAbpApplicationModule),
             typeof(AbpAutofacModule)
            )]
        public class MCodeAbpWebModule : AbpModule
        {
            /// <summary>
            /// 将你的服务添加到依赖注入系统并配置其他模块的
            /// </summary>
            /// <param name="context"></param>
            /// <returns></returns>
            public override Task ConfigureServicesAsync(ServiceConfigurationContext context)
            {
                var service = context.Services;
    
                //设置api格式
                service.AddControllers();
    
                //动态Api
                Configure<AbpAspNetCoreMvcOptions>(options =>
                {
                    options.ConventionalControllers.Create(typeof(MCodeAbpApplicationModule).Assembly, options => options.RemoteServiceName = "v1");
                    //统一前缀
                    options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app");
                });
    
                ///配置 Swagger
                service.AddAbpSwaggerGen(options =>
                {
                    var serviceProvider = service.BuildServiceProvider();
    
                    var mvcOptions = serviceProvider.GetRequiredService<IOptions<AbpAspNetCoreMvcOptions>>();
    
                    var mvcSettings = mvcOptions.Value.ConventionalControllers.ConventionalControllerSettings.DistinctBy(x => x.RemoteServiceName);
    
                    options.SwaggerDoc("v1", new OpenApiInfo { Title = "mcode.abp.api", Version = "v1", Description = "mcode.abp.api" });
    
                    // 根据分组名称过滤 API 文档(必须) *****
                    options.DocInclusionPredicate((docName, apiDesc) =>
                    {
                        if (apiDesc.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
                        {
                            var settingOrNull = mvcSettings.Where(x => x.Assembly == controllerActionDescriptor.ControllerTypeInfo.Assembly).FirstOrDefault();
                            if (settingOrNull is not null)
                            {
                                return docName == settingOrNull.RemoteServiceName;
                            }
                        }
                        return false;
                    });
    
                    //配置模型标识,默认type.Name,名称一样,不同明明空间会报错,所以改成FullName,加上命名空间区分
                    options.CustomSchemaIds(type => type.FullName);
                });
    
                return Task.CompletedTask;
            }
    
            /// <summary>
            ///  在应用程序启动时执行代码
            /// </summary>
            /// <param name="context"></param>
            /// <returns></returns>
            public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
            {
                var app = context.GetApplicationBuilder();
    
                app.UseStaticFiles();
    
                app.UseRouting();
    
                app.UseSwagger();
                app.UseAbpSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "mcode.abp.api");
                });
    
                app.UseConfiguredEndpoints();
    
                return Task.CompletedTask;
            }
        }
    
    
        public class MCodeAbpApplicationModule : AbpModule
        {
    
        }
    
         /// <summary>
        ///扩展示例
        /// </summary>
        [Route("[controller]/[action]")]
        public class TestService : ApplicationService
        {
            /// <summary>
            /// 动态Api
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            [HttpGet]
            public string GetHelloWorld(string? name)
            {
                return name ?? "HelloWord";
            }
        }
    

    源码分析

    替换 IOC 容器

    通过 UseServiceProviderFactory() 方法 ,构建 Abp 自定义的 Autofac 容器工厂,实际上就是做了一层包装

    public static class AbpAutofacHostBuilderExtensions
    {
        public static IHostBuilder UseAutofac(this IHostBuilder hostBuilder)
        {
            //初始化AutoFac容器构建对象
            var containerBuilder = new ContainerBuilder();
    
            return hostBuilder.ConfigureServices((_, services) =>
                {
                    services.AddObjectAccessor(containerBuilder);
                })
                //注册Abp自定义的Autofac容器工厂
                .UseServiceProviderFactory(new AbpAutofacServiceProviderFactory(containerBuilder));
        }
    }
    

    添加 ABP 应用程序

    通过 AbpApplicationFactory 类工厂创建启动模块程序

    
        public async static Task<IAbpApplicationWithExternalServiceProvider> AddApplicationAsync<TStartupModule>(
            [NotNull] this IServiceCollection services,
            Action<AbpApplicationCreationOptions>? optionsAction = null)
            where TStartupModule : IAbpModule
        {
            return await AbpApplicationFactory.CreateAsync<TStartupModule>(services,  optionsAction);
        }
    
        /// <summary>
        ///  通过 AbpApplicationFactory 创建 ABP 应用程序
        /// </summary>
        /// <typeparam name="TStartupModule"></typeparam>
        /// <param name="services"></param>
        /// <param name="optionsAction"></param>
        /// <returns></returns>
        public async static Task<IAbpApplicationWithExternalServiceProvider> CreateAsync<TStartupModule>(
            [NotNull] IServiceCollection services,
            Action<AbpApplicationCreationOptions>? optionsAction = null)
            where TStartupModule : IAbpModule
        {
            var app = Create(typeof(TStartupModule), services, options =>
            {
                options.SkipConfigureServices = true;
                optionsAction?.Invoke(options);
            });
            //调用配置服务
            await app.ConfigureServicesAsync();
            return app;
        }
    

    创建 ABP 外部服务提供者

    AbpApplicationWithExternalServiceProvider 中构造方法只做了了一件事,就是添加自己到服务中去。
    核心是继承了 AbpApplicationBase 基类,实例化后会调用基类的构造方法

        /// <summary>
        /// 创建 ABP 外部服务提供者(实例化应用程序基类)
        /// </summary>
        /// <param name="startupModuleType"></param>
        /// <param name="services"></param>
        /// <param name="optionsAction"></param>
        /// <returns></returns>
        public static IAbpApplicationWithExternalServiceProvider Create(
            [NotNull] Type startupModuleType,
            [NotNull] IServiceCollection services,
            Action<AbpApplicationCreationOptions>? optionsAction = null)
        {
            //会实例化ABP应用程序基类
            return new AbpApplicationWithExternalServiceProvider(startupModuleType, services, optionsAction);
        }
    

    初始化 ABP 程序基类

    模块的初始化动作是在 AbpApplicationBase 基类开始的,在该基类当中除了注入模块相关的基础设施以外。
    还定义了模块的初始化方法,即 LoadModules() 方法,在该方法内部是调用的 IModuleLoader 去执行具体的加载操作

    /// <summary>
    /// 初始化 Abp 程序
    /// </summary>
    /// <param name="startupModuleType"></param>
    /// <param name="services"></param>
    /// <param name="optionsAction"></param>
    internal AbpApplicationBase(
        [NotNull] Type startupModuleType,
        [NotNull] IServiceCollection services,
        Action<AbpApplicationCreationOptions>? optionsAction)
    {
        Check.NotNull(startupModuleType, nameof(startupModuleType));
        Check.NotNull(services, nameof(services));
    
        StartupModuleType = startupModuleType;
        Services = services;
    
        services.TryAddObjectAccessor<IServiceProvider>();
    
        var options = new AbpApplicationCreationOptions(services);
        //将Services添加到配置中去
        optionsAction?.Invoke(options);
        //获取应用程序名称
        ApplicationName = GetApplicationName(options);
    
        //添加当前对象为各种服务实例
        services.AddSingleton<IAbpApplication>(this);
        services.AddSingleton<IApplicationInfoAccessor>(this);
        services.AddSingleton<IModuleContainer>(this);
        //添加环境变量
        services.AddSingleton<IAbpHostEnvironment>(new AbpHostEnvironment()
        {
            EnvironmentName = options.Environment
        });
    
        //添加日志、选项等
        services.AddCoreServices();
        //添加核心Abp服务,以及模块的四个应用程序生命周期
        services.AddCoreAbpServices(this, options);
    
       //读取所有的模块,并按照预加载、初始化、初始化完成的顺序执行其生命周期方法
        Modules = LoadModules(services, options);
    
        //默认为true,不执行
        if (!options.SkipConfigureServices)
        {
            ConfigureServices();
        }
    }
    

    添加核心 ABP 服务

    AddCoreServices() 方法中是添加包括常规的日志、选项、本地化。
    AddCoreAbpServices() 方法则是 添加 Abp 的核心服务,包括各种读取器,配置

        /// <summary>
        /// 添加核心服务
        /// </summary>
        /// <param name="services"></param>
        internal static void AddCoreServices(this IServiceCollection services)
        {
            //添加选项
            services.AddOptions();
            //添加日志
            services.AddLogging();
            //添加本地化
            services.AddLocalization();
        }
    
        /// <summary>
        /// 添加核心ABP服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="abpApplication"></param>
        /// <param name="applicationCreationOptions"></param>
        internal static void AddCoreAbpServices(this IServiceCollection services,
            IAbpApplication abpApplication,
            AbpApplicationCreationOptions applicationCreationOptions)
        {
            var moduleLoader = new ModuleLoader();
            var assemblyFinder = new AssemblyFinder(abpApplication);
            var typeFinder = new TypeFinder(assemblyFinder);
    
            if (!services.IsAdded<IConfiguration>())
            {
                services.ReplaceConfiguration(
                    ConfigurationHelper.BuildConfiguration(
                        applicationCreationOptions.Configuration
                    )
                );
            }
    
            //添加各种读取器和查找器
            services.TryAddSingleton<IModuleLoader>(moduleLoader);
            services.TryAddSingleton<IAssemblyFinder>(assemblyFinder);
            services.TryAddSingleton<ITypeFinder>(typeFinder);
            services.TryAddSingleton<IInitLoggerFactory>(new DefaultInitLoggerFactory());
    
            //添加 AbpApplication所在程序集的类型
            services.AddAssemblyOf<IAbpApplication>();
    
            services.AddTransient(typeof(ISimpleStateCheckerManager<>), typeof(SimpleStateCheckerManager<>));
    
            //配置生命周期选项
            services.Configure<AbpModuleLifecycleOptions>(options =>
            {
                options.Contributors.Add<OnPreApplicationInitializationModuleLifecycleContributor>();
                options.Contributors.Add<OnApplicationInitializationModuleLifecycleContributor>();
                options.Contributors.Add<OnPostApplicationInitializationModuleLifecycleContributor>();
                options.Contributors.Add<OnApplicationShutdownModuleLifecycleContributor>();
            });
        }
    

    读取模块

    进入 IModuleLoader 的默认实现 ModuleLoader,在它的 LoadModules() 方法中,基本逻辑如下:

    扫描当前应用程序的所有模块类,并构建模块描述对象。
    基于模块描述对象,使用拓扑排序算法来按照模块的依赖性进行排序。
    排序完成之后,遍历排序完成的模块描述对象,依次执行它们的三个生命周期方法。

        protected virtual IReadOnlyList<IAbpModuleDescriptor> LoadModules(IServiceCollection services, AbpApplicationCreationOptions options)
        {
            //通过ModelLoader实例读取模块,LoadModules的时候会将实例添加到容器中
            return services
                .GetSingletonInstance<IModuleLoader>()
                .LoadModules(
                    services,
                    StartupModuleType,
                    options.PlugInSources
                );
        }
    
            /// <summary>
        /// 读取模块
        /// </summary>
        /// <param name="services"></param>
        /// <param name="startupModuleType"></param>
        /// <param name="plugInSources"></param>
        /// <returns></returns>
        public IAbpModuleDescriptor[] LoadModules(
            IServiceCollection services,
            Type startupModuleType,
            PlugInSourceList plugInSources)
        {
            Check.NotNull(services, nameof(services));
            Check.NotNull(startupModuleType, nameof(startupModuleType));
            Check.NotNull(plugInSources, nameof(plugInSources));
            //获取模块说明
            var modules = GetDescriptors(services, startupModuleType, plugInSources);
            //排序
            modules = SortByDependency(modules, startupModuleType);
    
            return modules.ToArray();
        }
            /// <summary>
        /// 获取模块说明
        /// </summary>
        /// <param name="services"></param>
        /// <param name="startupModuleType"></param>
        /// <param name="plugInSources"></param>
        /// <returns></returns>
        private List<IAbpModuleDescriptor> GetDescriptors(
            IServiceCollection services,
            Type startupModuleType,
            PlugInSourceList plugInSources)
        {
            var modules = new List<AbpModuleDescriptor>();
    
            //查找Module
            FillModules(modules, services, startupModuleType, plugInSources);
            //添加到当前模块描述对象的 Dependencies 属性
            SetDependencies(modules);
    
            return modules.Cast<IAbpModuleDescriptor>().ToList();
        }
    
            /// <summary>
        /// 查找所有的模块
        /// </summary>
        /// <param name="modules"></param>
        /// <param name="services"></param>
        /// <param name="startupModuleType"></param>
        /// <param name="plugInSources"></param>
        protected virtual void FillModules(
            List<AbpModuleDescriptor> modules,
            IServiceCollection services,
            Type startupModuleType,
            PlugInSourceList plugInSources)
        {
            var logger = services.GetInitLogger<AbpApplicationBase>();
    
             //查找到所有的模块
            //All modules starting from the startup module
            foreach (var moduleType in AbpModuleHelper.FindAllModuleTypes(startupModuleType, logger))
            {
                //创建模块说明并添加到容器中去
                modules.Add(CreateModuleDescriptor(services, moduleType));
            }
    
            //Plugin modules
            foreach (var moduleType in plugInSources.GetAllModules(logger))
            {
                if (modules.Any(m => m.Type == moduleType))
                {
                    continue;
                }
    
                modules.Add(CreateModuleDescriptor(services, moduleType, isLoadedAsPlugIn: true));
            }
        }
    

    配置服务(注入上下文、执行其生命周期方法)

    创建完 Abp 应用程序后会调用 ConfigureServicesAsync() 方法 ,
    会执行每个模块中的:ConfigureServices()PreConfigureServices()PostConfigureServices() 方法等

        /// <summary>
        /// 配置服务
        /// </summary>
        /// <returns></returns>
        /// <exception cref="AbpInitializationException"></exception>
        public virtual async Task ConfigureServicesAsync()
        {
            CheckMultipleConfigureServices();
    
            //将服务配置上下文对象添加到容器中
            var context = new ServiceConfigurationContext(Services);
            Services.AddSingleton(context);
    
            //遍历所有的容器中的模块,并指定上下文对象
            foreach (var module in Modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    abpModule.ServiceConfigurationContext = context;
                }
            }
    
            //遍历执行模块中PreConfigureServicesAsync方法(ConfigureServices之前执行)
            foreach (var module in Modules.Where(m => m.Instance is IPreConfigureServices))
            {
                try
                {
                    await ((IPreConfigureServices)module.Instance).PreConfigureServicesAsync(context);
                }
                catch (Exception ex)
                {
                    throw new AbpInitializationException($"An error occurred during {nameof(IPreConfigureServices.PreConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex);
                }
            }
    
            var assemblies = new HashSet<Assembly>();
    
            ////遍历模块,将所有的模块中需要注入的进行注入
            foreach (var module in Modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    if (!abpModule.SkipAutoServiceRegistration)
                    {
                        foreach (var assembly in module.AllAssemblies)
                        {
                            if (!assemblies.Contains(assembly))
                            {
                                Services.AddAssembly(assembly);
                                assemblies.Add(assembly);
                            }
                        }
                    }
                }
    
                try
                {
                    //执行模块实例中的方法
                    await module.Instance.ConfigureServicesAsync(context);
                }
                catch (Exception ex)
                {
                    throw new AbpInitializationException($"An error occurred during {nameof(IAbpModule.ConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex);
                }
            }
    
            //遍历执行模块中PostConfigureServicesAsync方法(ConfigureServices之后执行)
            foreach (var module in Modules.Where(m => m.Instance is IPostConfigureServices))
            {
                try
                {
                    await ((IPostConfigureServices)module.Instance).PostConfigureServicesAsync(context);
                }
                catch (Exception ex)
                {
                    throw new AbpInitializationException($"An error occurred during {nameof(IPostConfigureServices.PostConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex);
                }
            }
    
            //遍历所有的容器中的模块,并清空上下文对象
            foreach (var module in Modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    abpModule.ServiceConfigurationContext = null!;
                }
            }
    
            _configuredServices = true;
    
            TryToSetEnvironment(Services);
        }
    

    组件自动注册源码分析

    ABP 提供了三种接口:ISingletonDependencyITransientDependencyIScopedDependency 接口的方式进行注入
    方便我们的类型/组件自动注册,这三种接口分别对应了对象的 单例、瞬时、范围 生命周期。
    只要任何类型/接口实现了以上任意接口,ABP vNext 就会在系统启动时候,将这些对象注册到 IoC 容器当中
    也可以通过 DependencyAttribute 特性 去标记服务的类型,指定服务的生命周期
    在模块系统调用模块的 ConfigureServicesAsync() 的时候,就会有一个 services.AddAssembly()方法,
    他会将模块的所属的程序集传入

            //ConfigureServices
            foreach (var module in Modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    //是否跳过服务的自动注册,默认为 false
                    if (!abpModule.SkipAutoServiceRegistration)
                    {
                        foreach (var assembly in module.AllAssemblies)
                        {
                            if (!assemblies.Contains(assembly))
                            {
                                //注入当前程序集
                                Services.AddAssembly(assembly);
                                assemblies.Add(assembly);
                            }
                        }
                    }
                }
    
                try
                {
                    module.Instance.ConfigureServices(context);
                }
                catch (Exception ex)
                {
                    throw new AbpInitializationException($"An error occurred during {nameof(IAbpModule.ConfigureServices)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex);
                }
            }
    
    

    通过获取规则注册器进行注册,Abp 框架中自带默认的注册器 DefaultConventionalRegistrar ,也可以自定义注册器
    通过实现 ConventionalRegistrarBase 抽象类去自定义

        public static IServiceCollection AddAssembly(this IServiceCollection services, Assembly assembly)
        {
            ///获得所有注册器,然后调用注册器的 AddAssembly 方法注册类型。
            foreach (var registrar in services.GetConventionalRegistrars())
            {
                registrar.AddAssembly(services, assembly);
            }
    
            return services;
        }
    
    //抽象基类
        public abstract class ConventionalRegistrarBase : IConventionalRegistrar
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="services"></param>
        /// <param name="assembly"></param>
        public virtual void AddAssembly(IServiceCollection services, Assembly assembly)
        {
            //获得程序集内的所有类型,过滤掉抽象类和泛型类型。
            var types = AssemblyHelper
                .GetAllTypes(assembly)
                .Where(
                    type => type != null &&
                            type.IsClass &&
                            !type.IsAbstract &&
                            !type.IsGenericType
                ).ToArray();
    
            AddTypes(services, types);
        }
    
        //添加类型
        public virtual void AddTypes(IServiceCollection services, params Type[] types)
        {
            foreach (var type in types)
            {
                AddType(services, type);
            }
        }
    
        public abstract void AddType(IServiceCollection services, Type type);
    }
    
    • 通过的默认注册器进行注册
    public class DefaultConventionalRegistrar : ConventionalRegistrarBase
    {
        /// <summary>
        /// 添加类型
        /// </summary>
        /// <param name="services"></param>
        /// <param name="type"></param>
        public override void AddType(IServiceCollection services, Type type)
        {
            //如果标记了:DisableConventionalRegistrationAttribute特性的,不进行注入
            if (IsConventionalRegistrationDisabled(type))
            {
                return;
            }
    
            //获取Dependency依赖特性
            var dependencyAttribute = GetDependencyAttributeOrNull(type);
    
            //获取生命周期
            var lifeTime = GetLifeTimeOrNull(type, dependencyAttribute);
    
            if (lifeTime == null)
            {
                return;
            }
    
            //转成服务标识
            var exposedServiceAndKeyedServiceTypes = GetExposedKeyedServiceTypes(type).Concat(GetExposedServiceTypes(type).Select(t => new ServiceIdentifier(t))).ToList();
    
            //生成服务
            TriggerServiceExposing(services, type, exposedServiceAndKeyedServiceTypes);
    
            foreach (var exposedServiceType in exposedServiceAndKeyedServiceTypes)
            {
                var allExposingServiceTypes = exposedServiceType.ServiceKey == null
                    ? exposedServiceAndKeyedServiceTypes.Where(x => x.ServiceKey == null).ToList()
                    : exposedServiceAndKeyedServiceTypes.Where(x => x.ServiceKey?.ToString() == exposedServiceType.ServiceKey?.ToString()).ToList();
    
                //创建服务描述
                var serviceDescriptor = CreateServiceDescriptor(
                    type,
                    exposedServiceType.ServiceKey,
                    exposedServiceType.ServiceType,
                    allExposingServiceTypes,
                    lifeTime.Value
                );
    
                if (dependencyAttribute?.ReplaceServices == true)
                {
                    services.Replace(serviceDescriptor);
                }
                else if (dependencyAttribute?.TryRegister == true)
                {
                    services.TryAdd(serviceDescriptor);
                }
                else
                {
                    services.Add(serviceDescriptor);
                }
            }
        }
    }
    
    • GetLifeTimeOrNull 方法中 获取生命周期
        /// <summary>
        /// 获取生命周期
        /// </summary>
        /// <param name="type"></param>
        /// <param name="dependencyAttribute"></param>
        /// <returns></returns>
        protected virtual ServiceLifetime? GetLifeTimeOrNull(Type type, DependencyAttribute? dependencyAttribute)
        {
            // 特性中设置了生命周期或者继承了接口
            return dependencyAttribute?.Lifetime ?? GetServiceLifetimeFromClassHierarchy(type) ?? GetDefaultLifeTimeOrNull(type);
        }
    
        /// <summary>
        /// 从接口中获取生命周期
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        protected virtual ServiceLifetime? GetServiceLifetimeFromClassHierarchy(Type type)
        {
            if (typeof(ITransientDependency).GetTypeInfo().IsAssignableFrom(type))
            {
                return ServiceLifetime.Transient;
            }
    
            if (typeof(ISingletonDependency).GetTypeInfo().IsAssignableFrom(type))
            {
                return ServiceLifetime.Singleton;
            }
    
            if (typeof(IScopedDependency).GetTypeInfo().IsAssignableFrom(type))
            {
                return ServiceLifetime.Scoped;
            }
    
            return null;
        }
    
    

    初始化 ABP 应用程序

    • 通过 await app.InitializeApplicationAsync(); 方法会初始化应用程序,然后执行每一个模块中的生命周期的方法
        /// <summary>
        /// 异步初始化 ABP 应用程序
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public async static Task InitializeApplicationAsync([NotNull] this IApplicationBuilder app)
        {
            Check.NotNull(app, nameof(app));
    
            app.ApplicationServices.GetRequiredService<ObjectAccessor<IApplicationBuilder>>().Value = app;
            var application = app.ApplicationServices.GetRequiredService<IAbpApplicationWithExternalServiceProvider>();
            var applicationLifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>();
    
            //注册程序生命周期停止事件
            applicationLifetime.ApplicationStopping.Register(() =>
            {
                //执行 Abp程序中的 ShutdownAsync 方法, 会调用每个模块中的 ShutdownAsync 方法
                AsyncHelper.RunSync(() => application.ShutdownAsync());
            });
    
            //释放 Abp 应用
            applicationLifetime.ApplicationStopped.Register(() =>
            {
                application.Dispose();
            });
    
            // 执行 初始化 Abp 方法 ,初始化 每个模块,执行每一个模块中的 InitializeAsync 方法
            await application.InitializeAsync(app.ApplicationServices);
        }
    
    • 初始化每一个模块生命周期方法
       /// <summary>
       /// 设置服务提供者
       /// </summary>
       /// <param name="serviceProvider"></param>
        protected virtual void SetServiceProvider(IServiceProvider serviceProvider)
        {
            ServiceProvider = serviceProvider;
            ServiceProvider.GetRequiredService<ObjectAccessor<IServiceProvider>>().Value = ServiceProvider;
        }
    
        /// <summary>
        /// 初始化模块
        /// </summary>
        /// <returns></returns>
        protected virtual async Task InitializeModulesAsync()
        {
            using (var scope = ServiceProvider.CreateScope())
            {
                WriteInitLogs(scope.ServiceProvider);
                await scope.ServiceProvider
                    .GetRequiredService<IModuleManager>() //初始化模块
                    .InitializeModulesAsync(new ApplicationInitializationContext(scope.ServiceProvider));
            }
        }
    
        /// <summary>
        /// 初始化模块
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        /// <exception cref="AbpInitializationException"></exception>
        public virtual async Task InitializeModulesAsync(ApplicationInitializationContext context)
        {
            // 原先在 AddCoreAbpServices() 方法中 配置的 生命周期,
            foreach (var contributor in _lifecycleContributors)
            {
                foreach (var module in _moduleContainer.Modules)
                {
                    try
                    {
                        //执行每个生命周期(加载之前、加载中、加载之后)中的 初始化方法
                        await contributor.InitializeAsync(context, module.Instance);
                    }
                    catch (Exception ex)
                    {
                        throw new AbpInitializationException($"An error occurred during the initialize {contributor.GetType().FullName} phase of the module {module.Type.AssemblyQualifiedName}: {ex.Message}. See the inner exception for details.", ex);
                    }
                }
            }
    
            _logger.LogInformation("Initialized all ABP modules.");
        }
    
    • 四个生命周期 OnApplicationInitializationModuleLifecycleContributor
      OnPreApplicationInitializationModuleLifecycleContributor
      OnPostApplicationInitializationModuleLifecycleContributor
      OnApplicationShutdownModuleLifecycleContributor 中的方法,实际就是调用到具体模块中的生命周期各个方法
    public class OnApplicationInitializationModuleLifecycleContributor : ModuleLifecycleContributorBase
    {
        public async override Task InitializeAsync(ApplicationInitializationContext context, IAbpModule module)
        {
            if (module is IOnApplicationInitialization onApplicationInitialization)
            {
                await onApplicationInitialization.OnApplicationInitializationAsync(context);
            }
        }
    
        public override void Initialize(ApplicationInitializationContext context, IAbpModule module)
        {
            (module as IOnApplicationInitialization)?.OnApplicationInitialization(context);
        }
    }
    
    public class OnApplicationShutdownModuleLifecycleContributor : ModuleLifecycleContributorBase
    {
        public async override Task ShutdownAsync(ApplicationShutdownContext context, IAbpModule module)
        {
            if (module is IOnApplicationShutdown onApplicationShutdown)
            {
                await onApplicationShutdown.OnApplicationShutdownAsync(context);
            }
        }
    
        public override void Shutdown(ApplicationShutdownContext context, IAbpModule module)
        {
            (module as IOnApplicationShutdown)?.OnApplicationShutdown(context);
        }
    }
    
    public class OnPreApplicationInitializationModuleLifecycleContributor : ModuleLifecycleContributorBase
    {
        public async override Task InitializeAsync(ApplicationInitializationContext context, IAbpModule module)
        {
            if (module is IOnPreApplicationInitialization onPreApplicationInitialization)
            {
                await onPreApplicationInitialization.OnPreApplicationInitializationAsync(context);
            }
        }
    
        public override void Initialize(ApplicationInitializationContext context, IAbpModule module)
        {
            (module as IOnPreApplicationInitialization)?.OnPreApplicationInitialization(context);
        }
    }
    
    public class OnPostApplicationInitializationModuleLifecycleContributor : ModuleLifecycleContributorBase
    {
        public async override Task InitializeAsync(ApplicationInitializationContext context, IAbpModule module)
        {
            if (module is IOnPostApplicationInitialization onPostApplicationInitialization)
            {
                await onPostApplicationInitialization.OnPostApplicationInitializationAsync(context);
            }
        }
    
        public override void Initialize(ApplicationInitializationContext context, IAbpModule module)
        {
            (module as IOnPostApplicationInitialization)?.OnPostApplicationInitialization(context);
        }
    }