文章目录

生命周期

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

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

加载流程

  1. 进入到Startup
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddApplication<xxxManagementHttpApiHostModule>();
}
}
  1. 查看AddApplication源码会调用AbpApplicationFactory.CreateAsync
public async static Task<IAbpApplicationWithExternalServiceProvider> CreateAsync(
[NotNull] Type startupModuleType,
[NotNull] IServiceCollection services,
Action<AbpApplicationCreationOptions>? 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<AbpApplicationCreationOptions>? optionsAction
) : base(
startupModuleType,
services,
optionsAction)
{
services.AddSingleton<IAbpApplicationWithExternalServiceProvider>(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<AbpApplicationCreationOptions>? 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<Assembly>(); //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<IConfiguration>())
{
services.ReplaceConfiguration(
ConfigurationHelper.BuildConfiguration(
applicationCreationOptions.Configuration
)
);
}
services.TryAddSingleton<IModuleLoader>(moduleLoader);
services.TryAddSingleton<IAssemblyFinder>(assemblyFinder);
services.TryAddSingleton<ITypeFinder>(typeFinder);
services.TryAddSingleton<IInitLoggerFactory>(new DefaultInitLoggerFactory());
services.AddAssemblyOf<IAbpApplication>();
services.AddTransient(typeof(ISimpleStateCheckerManager<>), typeof(SimpleStateCheckerManager<>));
// 注册生命周期
services.Configure<AbpModuleLifecycleOptions>(options =>
{
// OnPreApplicationInitialization
options.Contributors.Add<OnPreApplicationInitializationModuleLifecycleContributor>();
// OnApplicationInitialization
options.Contributors.Add<OnApplicationInitializationModuleLifecycleContributor>();
// OnPostApplicationInitialization
options.Contributors.Add<OnPostApplicationInitializationModuleLifecycleContributor>();
// OnApplicationShutdown
options.Contributors.Add<OnApplicationShutdownModuleLifecycleContributor>();
});
}

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

  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

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

文章目录

Abp vNext 模块加载机制的更多相关文章

  1. 【前端】CommonJS的模块加载机制

    CommonJS的模块加载机制 CommonJS模块的加载机制是,输入的是被输出的值的拷贝.也就是说,一旦输出一个值,模块内部的变化就影响不到这个值. 例如: // lib.js var counte ...

  2. Dojo初探之1:AMD规范,编写符合AMD规范(异步模块加载机制)的模块化JS(其中dojo采用1.11.2版本)

    一.AMD规范探索 1.AMD规范(即异步模块加载机制) 我们在接触js的时候,一般都是通过各种function来定义一些方法,让它们帮我们做一些事情,一个js可以包含很多个js,而这些functio ...

  3. nodejs(13)模块加载机制

    模块加载机制 优先从缓存中加载 当一个模块初次被 require 的时候,会执行模块中的代码,当第二次加载相同模块的时候,会优先从缓存中查找,看有没有这样的一个模块! 好处:提高模块的加载速度:不需要 ...

  4. Skywalking-13:Skywalking模块加载机制

    模块加载机制 基本概述 Module 是 Skywalking 在 OAP 提供的一种管理功能特性的机制.通过 Module 机制,可以方便的定义模块,并且可以提供多种实现,在配置文件中任意选择实现. ...

  5. nodejs之模块加载机制

    nodejs模块加载原理 node加载模块步骤: 1) 路径分析 (如判断是不是核心模块.是绝对路径还是相对路径等) 2) 文件定位 (文件扩展名分析, 目录和包处理等细节) 3) 编译执行 原生模块 ...

  6. Abp 中 模块 加载及类型自动注入 源码学习笔记

    注意 互相关联多使用接口注册,所以可以 根据需要替换. 始于 Startup.cs 中的  通过 AddApplication 扩展方法添加 Abp支持 1 services.AddApplicati ...

  7. Node.js中模块加载机制

    1.模块查找规则-当模块拥有路径但没有后缀时:(require(‘./find’)) require方法根据模块路径查找模块,如果是完整路径,直接引入模块: 如果模块后缀省略,先找同名JS文件,再找同 ...

  8. node模块加载机制。

  9. javascript 异步模块加载 简易实现

    在javascript是没有类似java或其他语言的模块概念的,因此也不可能通过import或using等关键字来引用模块,这样造成了复杂项目中前端代码混乱,变量互相影响等. 因此在复杂项目中引入AM ...

  10. 也谈模块加载,吐槽CMD

    先吐槽CMD,不要没头没脑的搞出个CMD,没意思. 大家都看AMD好了,异步模块加载机制,CMD并没有改变这个模式. 模块加载的关口就是getCurrentScript,每次define被调用的时候, ...

随机推荐

  1. Python Joblib库使用学习总结

    实践环境 python 3.6.2 Joblib 简介 Joblib是一组在Python中提供轻量级流水线的工具.特别是: 函数的透明磁盘缓存和延迟重新计算(记忆模式) 简单易用的并行计算 Jobli ...

  2. 前端vue 宫格组件提供常见九宫格菜单组件,扩充性好,可切换九宫格 十二宫格 十五宫格

    快速实现vue uni-app宫格组件提供常见九宫格菜单组件,扩充性好,可切换九宫格 十二宫格 十五宫格; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net. ...

  3. PB从入坑到放弃(一)第一个HelloWorld程序

    前言 网上关于PowerBuilder的资料确实是少之又少. 为了方便,后面我们都用pb 来代替PowerBuilder 说到这不得不来说说自己的pb入坑经历, 自己也不是计算机科班出生. 刚到公司面 ...

  4. 固定型思维 VS 成长型思维

    回顾进入职场工作以来,对比曾经的学生时代,如果让我讲一个对自己影响最大的改变,那就是思维模式的一个转变. 具体来说,就是从一个典型的固定型思维转变成一个具备有成长型思维的人. 当然,我不敢妄称自己已经 ...

  5. 【C#/.NET】RESTful风格的Post请求与CreateAtAction

    ​  目录 引言 实现步骤 概念介绍 创建控制器 总结 引言 在构建Web应用程序时,遵循RESTful风格的API设计原则能够使我们的系统更加灵活.可扩展和易于维护.其中,Post请求在创建资源时起 ...

  6. 通用权限系统-Dozer对象转换

    Dozer对象转换 介绍 Dozer 是一个 Java Bean 到 Java Bean 的映射器,它可以递归地将数据从一个对象复制到另一个.通常情况下,这些Java Beans将是不同的复杂类型. ...

  7. 三级缓存---解决 Spring 循环依赖

    1. 循环依赖 1.1 什么是循环依赖 首先,什么是循环依赖?这个其实好理解,就是两个 Bean 互相依赖,类似下面这样: """ @Service public cla ...

  8. CMU15-445 Project3 Query Execution心得

    Project3 Query Execution 心得 一.概述 首先要说:这个 project很有趣很硬核!从这个 project 开始才感觉自己在数据库方面真正成长了! 第一个 project : ...

  9. MIT 6.5840 Raft Implementation(2A, Leader Election)

    Raft实现思路+细节 2A 任务分解 总体来说,2A中主要的任务就是选出领导人,在选出领导人的时候,我们要遵循下图. 在2A中,由于并没有出现日志复制,所以我们只需要考察两者的任期是否相等,以及接收 ...

  10. GitHub搜索指令教程

    in:根据某个关键词来进行检索 关键词: name:项目名称 description:项目描述 readme:项目帮助文档 语法: 需要检索的内容:in:name或description或readme ...