

ABP - 模块加载机制 - 啊晚
source link: https://www.cnblogs.com/wewant/p/17125189.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

ABP - 模块加载机制
Abp是一个基于模块化开发的应用程序框架,提供了模块化基础的架构和模块化加载的引擎。
一个模块是对一个功能点的封装,可以独立成为一个包,实现了松耦合的代码组织方式。Abp框架的基本思想就是模块开发,模块就想乐高中的一块块积木,在项目中将不同功能点的模块引用进来,就像搭积木一样构建成一个成品。
模块化的实现
通过在一个程序集中,创建一个模块类,继承AbpModule类,就可以很简单的将这个程序集作为Abp框架中的一个模块。如下面的代码,就是一个模块类的定义。
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpDddApplicationModule),
typeof(AbpObjectExtendingModule)
)]
public class BaseApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<BaseApplicationModule>();
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
base.OnApplicationInitialization(context);
}
}
AbpModule是 abp框架的模块基础类,一个类库可以通过一个继承此类的类,声明为一个模块。通过对AbpModule类的查看,可以看到这是一个抽象类,它很好的遵循了接口隔离原则。

一个模块就是一个完整的功能点,往往需要对其依赖的一些东西进行配置,如数据库连接、如配置文件读取等。Abp引擎通过将.net Core管道和容器传递,使得模块中可以配置自己的依赖注入和请求管道,而不需要在外部使用的时候添加一大堆配置,这样就达到了独立开放,开箱即用的目的。
通过重写PreConfigureServices
、ConfigureServices
、PostConfigureServices
这三个方法,可以在模块内部完成该模块的依赖注入配置。通过重写OnPreApplicationInitialization
、OnApplicationInitialization
、OnPostApplicationInitialization
、OnApplicationShutdown
这四个方法可完成模块在应用程序生命周期中的配置,在应用程序启动或者停止的时候做一些操作,也可以对asp.net Core的请求管道进行操作,例如加入自己的中间件。这些方法大家也并不陌生,和Asp.net Core中Startup类中的方法类似。
模块之间可以引用,并且设置模块的依赖关系,一个模块加载时,会先加载其依赖的模块。通过DependsOnAttribute可以指定模块依赖的模块,形成一个依赖链,Abp引擎启动时加载模块时,会先加载依赖模块。
Volo.Abp.Core 核心包
Volo.Abp.Core是Abp框架的核心包,关于Abp模块化的实现都在这个包中,我们可以通过对这个包的源码的研究,看下Abp模块化的实现方式。
首先,从Volo.Abp.Core的源码中,可以看到这个包也依赖于一些第三方包。

Fody: 可以在编译过程中拦截vs行为,动态地将一些代码添加到dll中,实现静态AOP的功能。
JetBrains: 提供一些数据标识,可以在编译期间对参数进行检查,减少bug
Nito:能够在使用Lock排他锁的时候,使用await异步的方式
SoureLink:支持在安装nuget包之后,动态地从git中下载源码以供调试,需要在vs中设置启用源程序调试
System.Collection.Immutable: 不可变集合,不可以往集合add
System.Linq.Dynamic.Core:动态linq,将强类型的Linq表达式变成字符串的方式进行操作
模块加载过程
ABP框架的启动过程,最根本的就是模块的装载过程。
众所周知,asp.net core程序的启动类时startup类,而在abp框架中,startup类却很简单,虽然代码简单,但是这两个方法却不简单,正是通过这两个方法,将asp.net core中的请求转移到abp框架中来处理。

以AddApplication<TStartupModule>()
扩展方法作为入口,通过查看源码,可以看到内部是通过AbpApplicationFactory
创建了一个abp应用程序的驱动AbpApplicationWithExternalServiceProvider
,在这个驱动类中完成了对abp框架启动的配置和操作。


AbpApplicationFactory
: abp应用启动的基本方式,是整个程序的入口,也是研究模加载机制的入口。根据使用的依赖注入容器的不同,提供两类的Create方法的重载。
应用程序引擎(容器)初始化时,通过应用程序引擎IAbpAppliaction
,即AbpApplicationWithExternalServiceProvider
,拿到各个模块信息(通过模块描述),执行各个模块中配置好的依赖注入。
而通过InitializeApplication(this IApplicationBuilder app)
方法,可以看到也是通过容器拿到驱动,即AbpApplicationWithExternalServiceProvider
示例,然后调用了Initialize(IServiceProvider serviceProvider)
方法。

ABP框架应用程序启动,模块加载整个过程涉及到了AbpApplicationFactory
、AbpApplicationWithExternalServiceProvider
、AbpApplicationBase
、IModuleLoader
、IModuleManager
等类和接口,这里不好把这些源码都列出来,所以就整理了一下简单的流程和调用关系。见下图。

abp应用程序初始化过程图

以上,就是对Abp应用程序启动和模块加载机制的整理.
除此之外,volo.abp.core类库中还提供了一些工具类和扩展方法,都是很好用的,就算不用abp框架的童鞋也可以借鉴其中的写法,或者直接拿到自己项目中使用。
有兴趣的童鞋可以自己再仔细查看一下源码。
ABP 系列总结:
目录:ABP 系列总结
上一篇:ABP - 初识 ABP
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK