using MAX.Framework.Interfaces; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; namespace MAX.Framework.DependencyInjection { /// /// 宿主(Program.cs)入口:模块两阶段装配。 /// /// var builder = WebApplication.CreateBuilder(args); /// builder.AddStoreHub(); // 阶段一:服务注册(自动执行所有 IModule.AddModule) /// /// var app = builder.Build(); /// // ... 宿主自己的中间件、认证、端点 ... /// app.UseStoreHubModules(); // 阶段二:管道装配(自动执行所有 IModule.UseModule) /// app.Run(); /// /// public static class HostBuilderExtensions { /// /// 在 上注册应用框架服务: /// 等价于 builder.Services.AddStoreHub(builder.Configuration, builder.Environment), /// 区别是会把配置与环境一起包装成 交给各模块。 /// public static WebApplicationBuilder AddStoreHub(this WebApplicationBuilder builder) { builder.Services.AddStoreHub(builder.Configuration, builder.Environment); return builder; } /// /// 执行所有模块的管道阶段():注册中间件、看板、Map 端点等。 /// 必须在 builder.Build() 之后、app.Run() 之前调用; /// 建议放在 UseAuthorization() 之后、MapControllers() 之前。 /// public static WebApplication UseStoreHubModules(this WebApplication app) { // 宿主没调用过 AddStoreHub() 时容器里没有注册表,直接返回即可 ModuleRegistry? registry = app.Services.GetService(); if (registry is null) { return app; } foreach (IModule module in registry.Modules) { try { module.UseModule(app); } catch (Exception ex) { throw new InvalidOperationException($"模块 {module.GetType().FullName} 的 UseModule 执行失败。", ex); } } return app; } } }