模块化
ABP框架旨在支持构建完全模块化的应用程序和系统,其中每个模块可包含实体、服务、数据库集成、API、UI组件等;
- 本文档介绍模块系统的基础知识。
- 模块化单体应用开发教程 详细说明并演示如何使用ABP构建模块化单体应用。
- 预构建应用模块 可直接用于任何类型的应用程序。
- 模块启动模板 是创建新可重用应用模块的快速入门方式。
- 模块开发最佳实践指南 介绍了基于领域驱动设计(DDD) 原则和分层开发可重用应用模块的最佳实践。遵循此指南设计的模块将独立于数据库,并可在需要时部署为微服务。
- ABP CLI 提供支持模块化开发的命令。
- 框架所有其他特性均与模块化系统兼容。
模块类
每个模块应定义一个模块类。定义模块类最简单的方式是创建继承自AbpModule的类,如下所示:
public class BlogModule : AbpModule
{
}
配置依赖注入与其他模块
ConfigureServices方法
ConfigureServices是将服务添加到依赖注入系统并配置其他模块的主要方法。示例:
这些方法也有异步版本,如果需要在方法内进行异步调用,请重写异步版本而非同步版本。
public class BlogModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
//...
}
}
可按微软 文档 所述逐一注册依赖项。但ABP拥有约定式依赖注册系统,可自动注册程序集中的所有服务。有关依赖注入系统的更多信息,请参阅 依赖注入 文档。
也可通过此方式配置其他服务和模块。示例:
public class BlogModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
//为应用程序配置默认连接字符串
Configure<AbpDbConnectionOptions>(options =>
{
options.ConnectionStrings.Default = "......";
});
}
}
ConfigureServices方法也有异步版本:ConfigureServicesAsync。如果需要在方法内进行异步调用(使用await关键字),请重写异步版本而非同步版本。如果同时重写异步和同步版本,仅执行异步版本。
有关配置系统的更多信息,请参阅 配置 文档。
服务配置前后处理
AbpModule类还定义了PreConfigureServices和PostConfigureServices方法,用于在所有其他模块的ConfigureServices方法执行前后编写代码。
这些方法也有异步版本。如果需要在方法内进行异步调用,请重写异步版本而非同步版本。
应用程序初始化
所有模块的服务配置完成后,应用程序通过初始化所有模块启动。在此阶段,可从IServiceProvider解析服务,因其已准备就绪。
OnApplicationInitialization方法
可重写OnApplicationInitialization方法,在应用程序启动时执行代码。
示例:
public class BlogModule : AbpModule
{
public override void OnApplicationInitialization(
ApplicationInitializationContext context)
{
var myService = context.ServiceProvider.GetService<MyService>();
myService.DoSomething();
}
}
OnApplicationInitialization方法也有异步版本。如果需要在方法内进行异步调用(使用await关键字),请重写异步版本而非同步版本。
示例:
public class BlogModule : AbpModule
{
public override Task OnApplicationInitializationAsync(
ApplicationInitializationContext context)
{
var myService = context.ServiceProvider.GetService<MyService>();
await myService.DoSomethingAsync();
}
}
如果同时重写异步和同步版本,仅执行异步版本。
OnApplicationInitialization通常由启动模块用于构建ASP.NET Core应用程序的中间件管道。
示例:
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
public class AppModule : AbpModule
{
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvcWithDefaultRoute();
}
}
若模块需要,也可执行启动逻辑。
应用程序初始化前后处理
AbpModule类还定义了OnPreApplicationInitialization和OnPostApplicationInitialization方法,用于在所有其他模块的OnApplicationInitialization方法执行前后编写代码。
这些方法也有异步版本。如果需要在方法内进行异步调用,请重写异步版本而非同步版本。
应用程序关闭
最后,如需在应用程序关闭时执行代码,可重写OnApplicationShutdown方法。
此方法也有异步版本。如果需要在方法内进行异步调用,请重写异步版本而非同步版本。
模块依赖
在模块化应用程序中,一个模块依赖另一个或多个模块的情况很常见。若ABP模块依赖其他模块,必须声明[DependsOn]属性,如下所示:
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
[DependsOn(typeof(AbpAutofacModule))]
public class BlogModule
{
//...
}
可根据偏好使用多个DependsOn属性或将多个模块类型传递给单个DependsOn属性。
依赖模块可能依赖其他模块,但只需定义直接依赖。ABP在启动时检查应用程序的依赖图,并按正确顺序初始化/关闭模块。
附加模块程序集
ABP自动将模块的所有服务注册到 依赖注入 系统。通过扫描定义模块类的程序集中的类型来发现服务类型。该程序集被视为模块的主程序集。
通常,每个程序集包含一个单独的模块类定义。然后模块使用DependsOn属性相互依赖,如前一节所述。但在某些罕见情况下,模块可能由多个程序集组成,仅其中一个定义模块类,且希望其他程序集成为模块的一部分。此时,可使用AdditionalAssembly属性,如下所示:
[DependsOn(...)] // 正常声明模块依赖
[AdditionalAssembly(typeof(BlogService))] // 目标程序集中的类型
public class BlogModule
{
//...
}
此示例中,假设BlogService类位于一个程序集(csproj)中,而BlogModule类位于另一个程序集(csproj)中。通过AdditionalAssembly定义,ABP将加载包含BlogService类的程序集作为博客模块的一部分。
注意BlogService仅是目标程序中任意选择的类型,仅用于指示相关程序集。可使用程序集中的任何类型。
警告:如需使用
AdditionalAssembly,请确保系统设计无误。以上例为例,BlogService类所在的程序集通常应拥有自己的模块类,且BlogModule应使用DependsOn属性依赖它。在可使用DependsOn属性时,请勿使用AdditionalAssembly属性。
框架模块 vs 应用模块
存在两种类型的模块。它们在结构上无差异,但按功能和目的分类:
- 框架模块:这些是框架的核心模块,如缓存、邮件、主题、安全、序列化、验证、EF Core集成、MongoDB集成等。它们不包含应用/业务功能,但通过提供通用基础设施、集成和抽象使日常开发更轻松。
- 应用模块:这些模块实现特定应用/业务功能,如博客、文档管理、身份管理、租户管理等。它们通常拥有自己的实体、服务、API和UI组件。参见 预构建应用模块 。
抠丁客


