文章目录

生命周期

  • 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. Eclipse的Console如何实现中文输出(Eclipse Display Chinese)

    最近遇到Eclipse的Console中文输出乱码的问题,现象如下: 在网上找到一些方法,一般均不好用,直到找到"如何在Eclipse控制台中显示汉字",链接如下 https:// ...

  2. rust随笔

    # 第二章 语言精要 ​ 好读书,不求甚解:每有会意,便欣然忘食. **动手,动手,动手!!!** ## 语句与表达式 Rust 中语法可以分成两大类:语句 statement 和表达式 expres ...

  3. 一文掌握设计模式(定义+UML类图+应用)

    一.引子 从学编程一开始就被告知,要想做一名优秀的程序员两大必要技能:1.源码阅读(JDK.C等底层语言封装) 2.设计模式(使用某种语言优雅的落地典型场景功能).一般随着工作年限的增长,被迫对底层语 ...

  4. 微信小程序常用的view、text、button、image组件

    [黑马程序员前端微信小程序开发教程,微信小程序从基础到发布全流程_企业级商城实战(含uni-app项目多端部署)] https://www.bilibili.com/video/BV1834y1676 ...

  5. JavaScript进阶指南: DOM与BOM操作,从初学者到专家,一步也能登天一篇文章就足够了

    DOM与BOM操作 复习链接: http://c.biancheng.net/view/9360.html 事件对象: https://www.runoob.com/jsref/dom-obj-eve ...

  6. 【Python】从同步到异步多核:测试桩性能优化,加速应用的开发和验证

    测试工作中常用到的测试桩mock能力 在我们的测试工作过程中,可能会遇到多个项目并行开发的时候,后端服务还没有开发完成,或者我们需要压测某个服务,这个服务测在试环境的依赖组件(如 MQ) 无法支撑我们 ...

  7. web系统字典统一中文翻译问题

    几乎每个web系统都离不开各种状态码.订单新建,待支付,未支付,已支付,待发货. 消息已读未读,任务待标记待审批已审批待流转已完成未完成.等等. 复杂一点的,会有多级状态码. 状态码超出3个的,一般都 ...

  8. 关于在modelsim中 仿真 ROM IP核 读取不了 mif文件 的解决方法

    在modelsim中 仿真 ROM IP核 读取不了 mif文件 . 出现状况: 显示无法打开 rom_8x256.mif 文件 .点开modelsim下面文件的内存列表,可看到内存全为0. 查看自身 ...

  9. node:windows script host 錯誤 console未定义

    错误背景 在开发npm包时,碰到此项报错 解决方案 选中任意js文件,选择打开方式,指定到node中即可

  10. [golang]字符串拼接

    前言 在go语言中,因为字符串只能被访问,不能被修改,所以进行字符串拼接的时候,golang都需要进行内存拷贝,造成一定的性能消耗. 方式1:操作符 + 特点:简单,可读性良好.每次拼接都会产生内存拷 ...