ABP VNext 系列:框架启动流程以及依赖注入原理和源码分析

简单介绍 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

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

csharp 复制代码
    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 容器工厂,实际上就是做了一层包装

csharp 复制代码
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 类工厂创建启动模块程序

csharp 复制代码
    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 基类,实例化后会调用基类的构造方法

csharp 复制代码
    /// <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 去执行具体的加载操作

csharp 复制代码
/// <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 的核心服务,包括各种读取器,配置

csharp 复制代码
    /// <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() 方法中,基本逻辑如下:

扫描当前应用程序的所有模块类,并构建模块描述对象。

基于模块描述对象,使用拓扑排序算法来按照模块的依赖性进行排序。

排序完成之后,遍历排序完成的模块描述对象,依次执行它们的三个生命周期方法。

csharp 复制代码
    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() 方法等

csharp 复制代码
    /// <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()方法,

他会将模块的所属的程序集传入

csharp 复制代码
        //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 抽象类去自定义

csharp 复制代码
    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);
}
  • 通过的默认注册器进行注册
csharp 复制代码
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 方法中 获取生命周期
csharp 复制代码
    /// <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(); 方法会初始化应用程序,然后执行每一个模块中的生命周期的方法
csharp 复制代码
    /// <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);
    }
  • 初始化每一个模块生命周期方法
csharp 复制代码
   /// <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 中的方法,实际就是调用到具体模块中的生命周期各个方法
csharp 复制代码
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);
    }
}