模块生命周期与 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必定在所有依赖它的业务模块之前完成ConfigureServices; - 环形依赖检测 (Cycle Detection):如果模块 A 依赖 B,而模块 B 依赖 A,引擎在编译期或启动期会直接抛出
InvalidModuleDependencyException并指明环形路径,阻断系统带病启动; - 隔离配置读取:每个模块只能通过
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();4. 相关架构决策与进阶推荐 (Related Deep Dives)
- 黄金样例:Sandbox 黄金样例全景拆解
- 多 Profile 发行:Profiles 多租户定制与元包发行机制
- 决策溯源:ADR 0203:模块物理目录结构与防腐隔离