项目

模块化

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类还定义了PreConfigureServicesPostConfigureServices方法,用于在所有其他模块的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类还定义了OnPreApplicationInitializationOnPostApplicationInitialization方法,用于在所有其他模块的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组件。参见 预构建应用模块

另请参阅

在本文档中