Skip to content
bitzorcas
中EN

Concept

模块生命周期与 Modularity 引擎

深度剖析 BitzOrcas.Modularity 编译期模块装配引擎:模块依赖图拓扑排序、ConfigureServices 与 UseModule 生命周期回调。

Last updated

模块生命周期与 Modularity 引擎 (Module Lifecycle & Modularity Engine)

在大型企业级单体(Modular Monolith)演进过程中,最常遇到的架构腐化是:各个业务模块的初始化逻辑直接杂糅在 Program.cs 中,导致入口文件膨胀至数千行,模块之间的启动顺序互相争抢、隐式依赖模糊不清。

BitzOrcas.Modern 通过 BitzOrcas.Modularity 引擎与 BitzOrcas.Modularity.Generator 源码生成器,将每个业务模块封装为具备明确生命周期、显式依赖声明与自动化依赖注入(DI)的自洽单元。


1. 模块定义契约:IModuleDefinition 与 [DependsOn]

每个模块在 Contracts 或 Application 层根目录下定义一个模块契约类,实现 IModuleDefinition 接口并声明对其他模块的前置依赖:

using System;
using BitzOrcas.Modularity;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace BitzOrcas.Modules.Litigation;
/// <summary>
/// 诉讼业务模块定义:声明对 Identity 与 Notifications 模块的强前置依赖
/// </summary>
[DependsOn(typeof(BitzOrcas.Platform.Identity.Contracts.IdentityModule))]
[DependsOn(typeof(BitzOrcas.Platform.Notifications.Contracts.NotificationsModule))]
public sealed class LitigationModule : IModuleDefinition
{
public string ModuleName => "Litigation";
public int Order => 100;
/// <summary>
/// 服务注册阶段:注册模块独有的仓储、领域服务与第三方客户端
/// </summary>
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// 1. 绑定模块独立配置
services.AddOptions<LitigationOptions>()
.Bind(configuration.GetSection("Modules:Litigation"))
.ValidateDataAnnotations();
// 2. 注册模块专用服务与适配器(由源生成器自动补齐大部分切片注册)
services.AddScoped<ILegalCaseNumberGenerator, LegalCaseNumberGenerator>();
}
/// <summary>
/// 中间件管线与端点挂载阶段:在 API 宿主就绪后执行
/// </summary>
public void UseModule(IApplicationBuilder app)
{
// 挂载模块专有的中间件(如特定 Webhook 回调路由或健康检查探针)
}
}

2. 拓扑排序与依赖图解析 (Topological Sort)

在宿主启动时,Modularity 引擎不会采用简单的字母顺序加载模块,而是自动构建有向无环图(DAG)并进行拓扑排序:

IdentityModule
(基础认证租户)

NotificationsModule
(站内信与通知)

WorkflowModule
(审批流引擎)

LitigationModule
(诉讼核心域)

LegalConnectorsModule
(外部法律云同步)

加载规则与生命周期保证

  1. 底层优先初始化:IdentityModule 必定在所有依赖它的业务模块之前完成 ConfigureServices;
  2. 环形依赖检测 (Cycle Detection):如果模块 A 依赖 B,而模块 B 依赖 A,引擎在编译期或启动期会直接抛出 InvalidModuleDependencyException 并指明环形路径,阻断系统带病启动;
  3. 隔离配置读取:每个模块只能通过 configuration.GetSection("Modules:<ModuleName>") 读取自身命名空间下的配置项,杜绝全局配置互相污染。

3. 宿主极简装配 (Program.cs)

得益于源生成器与模块化引擎,宿主 BitzOrcas.Api 的 Program.cs 保持极致的清爽整洁:

using BitzOrcas.Modularity;
var builder = WebApplication.CreateBuilder(args);
// 1. 扫描并自动装配所有发现的模块(拓扑排序执行 ConfigureServices)
builder.Services.AddModularMonolith(builder.Configuration);
var app = builder.Build();
// 2. 拓扑排序执行 UseModule 挂载中间件
app.UseModularMonolith();
app.Run();

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%