文章目录

生命周期

  • 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. 第三届陕西省大学生网络安全技能部分WP

    web easyrce 题目代码如下: <?php error_reporting(0); highlight_file(__FILE__); if (!empty($_GET['PK'])){ ...

  2. 前端Vue自定义简单实用中国省市区三级联动选择器

    前端Vue自定义简单实用中国省市区三级联动选择器, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13118 效果图如下: 使用方法 < ...

  3. 机器翻译技术的发展趋势:从API到深度学习

    目录 机器翻译技术的发展趋势:从API到深度学习 随着全球化的发展,机器翻译技术在各个领域得到了广泛的应用.机器翻译技术的核心是将源语言文本翻译成目标语言文本,其中涉及到语言模型.文本生成模型和翻译模 ...

  4. 跑得更快!华为云GaussDB以出色的性能守护“ERP的心脏”

    摘要:GaussDB已经全面支撑起MetaERP,在包括库存服务在内的9大核心模块中稳定运行,端到端业务效率得到10倍提升. 本文分享自华为云社区<跑得更快!华为云GaussDB以出色的性能守护 ...

  5. ShardingSphere5入门到实战

    ShardingSphere5入门到实战 第01章 高性能架构模式 互联网业务兴起之后,海量用户加上海量数据的特点,单个数据库服务器已经难以满足业务需要,必须考虑数据库集群的方式来提升性能.高性能数据 ...

  6. 基于Sa-Token实现微服务之前的单点登录

    修改配置文件,准备好四个域名 127.0.0.1 auth.server.com 127.0.0.1 user.server.com 127.0.0.1 third.server.com 127.0. ...

  7. 1.6 编写双管道ShellCode后门

    本文将介绍如何将CMD绑定到双向管道上,这是一种常用的黑客反弹技巧,可以让用户在命令行界面下与其他程序进行交互,我们将从创建管道.启动进程.传输数据等方面对这个功能进行详细讲解.此外,本文还将通过使用 ...

  8. html实现原生table并设置表格边框的两种方式

    虽然第三方表格插件多不胜数,但是很多场景还是需要用到原生<table>,掌握html原生table的实现方法,是前端开发的必备技能.例如:print-js打印.html2canvas生成图 ...

  9. Vue-Element UI 文件上传与下载

    项目结构 后端 前端 效果演示 上传文件 下载文件 Code 后端代码 跨域 /** * 跨域配置 * @author Louis * @date Jan 12, 2019 */ @Configura ...

  10. 6月有奖征文挑战,ZEGO开发者社区首季活动报名入口!

    前 言 哈喽 开发者们: ZEGO即构科技作为一家20年技术积累的音视频云服务商,已经为全球200+个国家的企业服务,单日通话时长突破30亿+分钟,现下即构开发者社区举办首期征文活动!本次征文活动围绕 ...