• Abp vNext 模块加载机制


    文章目录

    生命周期

    • PreConfigureServices 添加依赖注入或者其它配置之前
    • ConfigureServices 添加依赖注入或者其它配置
    • PostConfigureServices 添加依赖注入或者其它配置之后
    • OnPreApplicationInitialization 初始化所有模块之前
    • OnApplicationInitialization 初始化所有模块
    • OnPostApplicationInitialization 初始化所有模块之后
    • OnApplicationShutdown 应用关闭执行

    OnPreApplicationInitializationOnPostApplicationInitialization方法用来在OnApplicationInitialization之前或之后覆盖和编写你的代码.请注意,在这些方法中编写的代码将在所有其他模块的OnApplicationInitialization方法之前/之后执行.

    加载流程

    1. 进入到Startup
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication();
        }
    }
    
    1. 查看AddApplication源码会调用AbpApplicationFactory.CreateAsync
    public async static Task CreateAsync(
        [NotNull] Type startupModuleType,
        [NotNull] IServiceCollection services,
        Action? optionsAction = null)
    {
        var app = new AbpApplicationWithExternalServiceProvider(startupModuleType, services, options =>
        {
            options.SkipConfigureServices = true;
            optionsAction?.Invoke(options);
        });
        await app.ConfigureServicesAsync();
        return app;
    }
    
    1. 进入AbpApplicationWithExternalServiceProvider,我们可以看到继承AbpApplicationBase
    internal class AbpApplicationWithExternalServiceProvider : AbpApplicationBase, IAbpApplicationWithExternalServiceProvider
    {
        public AbpApplicationWithExternalServiceProvider(
            [NotNull] Type startupModuleType,
            [NotNull] IServiceCollection services,
            Action? optionsAction
            ) : base(
                startupModuleType,
                services,
                optionsAction)
        {
            services.AddSingleton(this);
        }
    
        void IAbpApplicationWithExternalServiceProvider.SetServiceProvider([NotNull] IServiceProvider serviceProvider)
        {
            Check.NotNull(serviceProvider, nameof(serviceProvider));
    
            // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
            if (ServiceProvider != null)
            {
                if (ServiceProvider != serviceProvider)
                {
                    throw new AbpException("Service provider was already set before to another service provider instance.");
                }
    
                return;
            }
    
            SetServiceProvider(serviceProvider);
        }
    
    1. 查看AbpApplicationBase构造函数
     internal AbpApplicationBase(
            [NotNull] Type startupModuleType,
            [NotNull] IServiceCollection services,
            Action? optionsAction)
        {
            services.AddCoreServices();
            services.AddCoreAbpServices(this, options);
            // 加载模块
            Modules = LoadModules(services, options);
        }
    
    1. 查看加载模块逻辑
    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();
    }
    

    生命周期

    在上面第二步我们可以看到有一个await app.ConfigureServicesAsync();

    • 在这个方法中可以看到依次执行每个模块的PreConfigureServices,ConfigureServices,PostConfigureServices
    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;
                }
            }
    
            //PreConfigureServices
            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();
    
            //ConfigureServices
            foreach (var module in Modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    if (!abpModule.SkipAutoServiceRegistration)
                    {
                        var assembly = module.Type.Assembly;
                        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);
                }
            }
    
            //PostConfigureServices
            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;
        }
    
    • 再次查看第四步中有一个services.AddCoreAbpServices(this, options);
      这个里面构造好其它的四个生命周期
    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())
        {
            services.ReplaceConfiguration(
                ConfigurationHelper.BuildConfiguration(
                    applicationCreationOptions.Configuration
                )
            );
        }
        services.TryAddSingleton(moduleLoader);
        services.TryAddSingleton(assemblyFinder);
        services.TryAddSingleton(typeFinder);
        services.TryAddSingleton(new DefaultInitLoggerFactory());
        services.AddAssemblyOf();
        services.AddTransient(typeof(ISimpleStateCheckerManager<>), typeof(SimpleStateCheckerManager<>));
        // 注册生命周期
        services.Configure(options =>
        {
            // OnPreApplicationInitialization
            options.Contributors.Add();
            // OnApplicationInitialization
            options.Contributors.Add();
            // OnPostApplicationInitialization
            options.Contributors.Add();
            // OnApplicationShutdown
            options.Contributors.Add();
        });
    }
    

    注册了这四个生命周期,在什么时候调用呢?请继续往下看。

    1. 继续回到Startup类
    public class Startup
    {
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
        {
            app.InitializeApplication();
        }
    }
    
    1. 查看InitializeApplication
    • 遍历刚刚注入的四个生命周期,执行Initialize初始化方法
    public void InitializeModules(ApplicationInitializationContext context)
    {
        foreach (var contributor in _lifecycleContributors)
        {
            foreach (var module in _moduleContainer.Modules)
            {
                try
                {
                    contributor.Initialize(context, module.Instance);
                }
                catch (Exception ex)
                {
                    //
                }
            }
        }
        _logger.LogInformation("Initialized all ABP modules.");
    }
    

    Abp vNext Pro

    如果觉得可以,不要吝啬你的小星星哦

    文章目录

  • 相关阅读:
    libmp4v2不完全指南封装g711a的坑
    LayUI之CRUD
    125. SAP UI5 进阶 - XML 视图里定义的 UI 控件,运行时实例化的技术细节剖析
    私有化部署的即时通讯平台,为企业移动业务安全保驾护航
    Django ModelForm编辑用户
    【Transformer专题】一、Attention is All You Need(Transformer)
    数据库和表的基本操作
    设备二维码金属铭牌铝牌定制
    参加微软学生开发者峰会,了解Azure和GitHub……
    Vue基础二之全局API、实例属性和全局配置,以及组件进阶(mixins)的详细教程(案列实现,详细图解,附源码)
  • 原文地址:https://www.cnblogs.com/WangJunZzz/p/17728392.html