registerModules static method
Register and load modules with dependency resolution
Validates upfront, then loads in correct order. Throws immediately on any error - no complex rollback.
Implementation
static Future<void> registerModules(
List<ZenModule> modules,
ZenScope scope,
) async {
if (modules.isEmpty) return;
// 1. Collect all dependencies
final allModules = _collectAllDependencies(modules);
// 2. Validate - throws if circular dependencies
_validateDependencyGraph(allModules);
// 3. Check all module dependencies are available
for (final module in allModules) {
for (final dep in module.dependencies) {
if (!_modules.containsKey(dep.name) &&
!allModules.any((m) => m.name == dep.name)) {
throw StateError(
'Missing dependency: "${dep.name}" required by "${module.name}"');
}
}
}
// 4. Calculate load order
final loadOrder = _calculateLoadOrder(allModules);
ZenLogger.logInfo(
'Loading ${loadOrder.length} modules: ${loadOrder.map((m) => m.name).join(' → ')}');
// 5. Load modules in dependency order
for (final module in loadOrder) {
// Skip if already loaded
if (_modules.containsKey(module.name)) {
ZenLogger.logDebug('⏭️ Skipped (already loaded): ${module.name}');
continue;
}
// Register dependencies
module.register(scope);
// Initialize
await module.onInit(scope);
// Mark as loaded
_modules[module.name] = module;
ZenLogger.logInfo('✅ Loaded: ${module.name}');
}
ZenLogger.logInfo('✅ All ${loadOrder.length} modules loaded successfully');
}