模块生命周期
Entity Engine 的模块生命周期管理提供了三阶段的模块初始化流程:配置设置、组件注册和数据初始化。这种分阶段设计确保了依赖关系的正确处理和系统的稳定启动。每个阶段都有明确的职责和执行顺序,让您能够安全、可靠地构建复杂的模块化应用。
三阶段生命周期概览
Entity Engine 采用分阶段的模块初始化策略,按照以下顺序执行:
1. 配置阶段 (setupConfig)
- 目的:设置模块配置、验证配置参数
- 执行时机:所有模块首先完成配置阶段
- 主要任务:设置默认配置、验证必需参数、环境适配
2. 组件阶段 (setupComponents)
- 目的:注册服务、组件和事件处理器
- 执行时机:所有模块配置完成后
- 主要任务:服务注册、组件注册、依赖注入
3. 数据阶段 (setupData)
- 执行时机:所有组件注册完成后
- 目的:执行数据迁移、初始化默认数据
- 主要任务:数据库迁移、创建默认数据、数据验证
模块注册与启动流程
基本启动流程
import { engine } from '@scenemesh/entity-engine';
import { MyModule } from './my-module';
// 1. 注册模块
engine.moduleRegistry.register(new MyModule());
// 2. 启动 Entity Engine(自动执行三阶段初始化)
await engine.start();
批量注册模块
// 注册多个模块
engine.moduleRegistry.registerAll([
new DatabaseModule(),
new AuthModule(),
new UserModule(),
new BlogModule()
]);
// 启动系统
await engine.start();
setupConfig 阶段详解
配置阶段是模块初始化的第一步,负责设置和验证模块配置。
基本配置设置
async setupConfig({ configManager, logger }) {
// 设置默认配置
configManager.setDefault(this.info.name, {
database: {
host: 'localhost',
port: 5432,
maxConnections: 10
},
cache: {
enabled: true,
ttl: 3600
},
logging: {
level: 'info'
}
});
logger.info(`${this.info.name} configuration initialized`);
}
配置验证
async setupConfig({ configManager, logger }) {
// 设置默认配置
configManager.setDefault(this.info.name, {
apiUrl: 'https://api.example.com',
apiKey: '',
timeout: 5000
});
// 获取配置进行验证
const config = configManager.get(this.info.name);
// 验证必需配置
if (!config.apiKey) {
throw new Error('API key is required for external service integration');
}
// 验证配置范围
if (config.timeout < 1000 || config.timeout > 30000) {
logger.warn('Timeout out of recommended range, adjusting to default');
configManager.set(`${this.info.name}.timeout`, 5000);
}
// 验证URL格式
try {
new URL(config.apiUrl);
} catch (error) {
throw new Error(`Invalid API URL: ${config.apiUrl}`);
}
logger.info('Configuration validated successfully');
}
环境特定配置
async setupConfig({ configManager, logger }) {
// 基础配置
const baseConfig = {
debug: false,
logLevel: 'warn',
cacheSize: 1000
};
// 根据环境调整配置
if (process.env.NODE_ENV === 'development') {
Object.assign(baseConfig, {
debug: true,
logLevel: 'debug',
cacheSize: 100
});
} else if (process.env.NODE_ENV === 'test') {
Object.assign(baseConfig, {
logLevel: 'error',
cacheSize: 50
});
}
configManager.setDefault(this.info.name, baseConfig);
// 从环境变量覆盖配置
const envOverrides = {};
if (process.env.LOG_LEVEL) {
envOverrides.logLevel = process.env.LOG_LEVEL;
}
if (process.env.CACHE_SIZE) {
envOverrides.cacheSize = parseInt(process.env.CACHE_SIZE);
}
if (Object.keys(envOverrides).length > 0) {
configManager.merge(this.info.name, envOverrides);
logger.info('Applied environment configuration overrides');
}
}
setupComponents 阶段详解
组件阶段负责注册服务、组件和建立依赖关系。
服务注册
async setupComponents({ serviceRegistry, componentRegistry, configManager, logger }) {
const config = configManager.get(this.info.name);
// 注册核心服务
serviceRegistry.register('DatabaseService',
new DatabaseService(config.database)
);
// 注册依赖其他服务的服务
const dbService = serviceRegistry.get('DatabaseService');
serviceRegistry.register('UserRepository',
new UserRepository(dbService)
);
// 注册缓存服务(如果启用)
if (config.cache.enabled) {
serviceRegistry.register('CacheService',
new CacheService(config.cache)
);
}
logger.info('Core services registered successfully');
}
组件注册
async setupComponents({ serviceRegistry, componentRegistry, logger }) {
// 注册视图组件
componentRegistry.registerView(new UserListView());
componentRegistry.registerView(new UserDetailView());
componentRegistry.registerView(new UserFormView());
// 注册数据适配器
componentRegistry.registerAdapter(new UserDataAdapter());
// 注册渲染器
componentRegistry.registerRenderer({
name: 'UserStatusRenderer',
slotName: 'status',
render: (data) => renderUserStatus(data)
});
logger.info('UI components registered successfully');
}
依赖注入和服务获取
async setupComponents({ serviceRegistry, configManager, logger }) {
// 获取依赖的服务
const dbService = serviceRegistry.get('DatabaseService');
const eventService = serviceRegistry.get('EventService');
if (!dbService) {
throw new Error('DatabaseService is required but not available');
}
// 注册需要依赖的服务
serviceRegistry.register('NotificationService',
new NotificationService(dbService, eventService)
);
// 可选依赖处理
const cacheService = serviceRegistry.get('CacheService');
if (cacheService) {
logger.info('Cache service available, enabling caching');
serviceRegistry.register('CachedUserService',
new CachedUserService(dbService, cacheService)
);
} else {
logger.warn('Cache service not available, using direct database access');
serviceRegistry.register('CachedUserService',
new UserService(dbService)
);
}
}
事件处理器注册
async setupComponents({ serviceRegistry, logger }) {
// 获取事件注册表
const eventRegistry = serviceRegistry.get('EventRegistry');
if (eventRegistry) {
// 注册事件处理器
eventRegistry.on('user.created', async (userData) => {
await this.handleUserCreated(userData);
});
eventRegistry.on('user.updated', async (userData) => {
await this.handleUserUpdated(userData);
});
eventRegistry.on('user.deleted', async (userId) => {
await this.handleUserDeleted(userId);
});
logger.info('Event handlers registered successfully');
}
}
private async handleUserCreated(userData) {
// 用户创建后的处理逻辑
const notificationService = serviceRegistry.get('NotificationService');
await notificationService.sendWelcomeEmail(userData);
}
setupData 阶段详解
数据阶段负责执行数据库迁移、创建默认数据和数据验证。
数据表创建
async setupData({ serviceRegistry, logger }) {
const dbService = serviceRegistry.get('DatabaseService');
try {
// 检查表是否存在
const tablesExist = await dbService.checkTables(['users', 'user_profiles']);
if (!tablesExist) {
// 创建用户表
await dbService.createTable('users', {
id: { type: 'string', primaryKey: true },
username: { type: 'string', unique: true, maxLength: 50 },
email: { type: 'string', unique: true, maxLength: 255 },
passwordHash: { type: 'string', maxLength: 255 },
status: { type: 'string', enum: ['active', 'inactive', 'suspended'], default: 'active' },
createdAt: { type: 'datetime', default: 'now()' },
updatedAt: { type: 'datetime', default: 'now()' }
});
// 创建用户资料表
await dbService.createTable('user_profiles', {
id: { type: 'string', primaryKey: true },
userId: { type: 'string', foreignKey: 'users.id' },
firstName: { type: 'string', maxLength: 50 },
lastName: { type: 'string', maxLength: 50 },
avatar: { type: 'string', nullable: true },
bio: { type: 'text', nullable: true },
preferences: { type: 'json', nullable: true }
});
logger.info('Database tables created successfully');
}
// 执行数据迁移
await this.runDataMigrations(dbService, logger);
} catch (error) {
logger.error('Data initialization failed:', error);
throw error;
}
}
数据迁移管理
private async runDataMigrations(dbService, logger) {
// 检查迁移表是否存在
await dbService.ensureTable('_migrations', {
version: { type: 'string', primaryKey: true },
appliedAt: { type: 'datetime', default: 'now()' }
});
// 定义迁移脚本
const migrations = [
{
version: '1.0.1',
description: 'Add user status column',
script: async (db) => {
await db.addColumn('users', 'status', {
type: 'string',
enum: ['active', 'inactive', 'suspended'],
default: 'active'
});
}
},
{
version: '1.1.0',
description: 'Create user preferences table',
script: async (db) => {
await db.createTable('user_preferences', {
userId: { type: 'string', primaryKey: true, foreignKey: 'users.id' },
theme: { type: 'string', default: 'light' },
language: { type: 'string', default: 'en' },
notifications: { type: 'json', default: '{}' }
});
}
}
];
// 执行未应用的迁移
for (const migration of migrations) {
const applied = await dbService.findOne('_migrations', { version: migration.version });
if (!applied) {
logger.info(`Applying migration ${migration.version}: ${migration.description}`);
try {
await migration.script(dbService);
await dbService.insert('_migrations', { version: migration.version });
logger.info(`Migration ${migration.version} applied successfully`);
} catch (error) {
logger.error(`Migration ${migration.version} failed:`, error);
throw error;
}
}
}
}
默认数据创建
async setupData({ serviceRegistry, configManager, logger }) {
const dbService = serviceRegistry.get('DatabaseService');
const config = configManager.get(this.info.name);
// 创建默认管理员用户
await this.createDefaultAdmin(dbService, config, logger);
// 创建默认角色
await this.createDefaultRoles(dbService, logger);
// 创建默认设置
await this.createDefaultSettings(dbService, config, logger);
}
private async createDefaultAdmin(dbService, config, logger) {
const adminExists = await dbService.findOne('users', { username: 'admin' });
if (!adminExists) {
const adminUser = {
id: generateId(),
username: 'admin',
email: config.admin?.email || 'admin@example.com',
passwordHash: await hashPassword(config.admin?.password || 'admin123'),
status: 'active'
};
await dbService.insert('users', adminUser);
// 创建管理员资料
await dbService.insert('user_profiles', {
id: generateId(),
userId: adminUser.id,
firstName: 'System',
lastName: 'Administrator',
bio: 'Default system administrator'
});
logger.info('Default administrator created');
logger.warn('Please change the default admin password immediately');
}
}
private async createDefaultRoles(dbService, logger) {
await dbService.ensureTable('roles', {
id: { type: 'string', primaryKey: true },
name: { type: 'string', unique: true },
description: { type: 'string' },
permissions: { type: 'json', default: '[]' }
});
const defaultRoles = [
{
name: 'admin',
description: 'System Administrator',
permissions: ['*']
},
{
name: 'user',
description: 'Regular User',
permissions: ['read:profile', 'update:profile']
},
{
name: 'guest',
description: 'Guest User',
permissions: ['read:public']
}
];
for (const role of defaultRoles) {
const exists = await dbService.findOne('roles', { name: role.name });
if (!exists) {
await dbService.insert('roles', {
id: generateId(),
...role
});
}
}
logger.info('Default roles created');
}
生命周期最佳实践
1. 配置阶段最佳实践
async setupConfig({ configManager, logger }) {
try {
// 1. 设置完整的默认配置
const defaultConfig = {
server: {
port: 3000,
host: '0.0.0.0',
cors: {
enabled: true,
origins: ['http://localhost:3000']
}
},
security: {
jwtSecret: '',
sessionTimeout: 3600000,
passwordPolicy: {
minLength: 8,
requireUppercase: true,
requireNumbers: true
}
}
};
configManager.setDefault(this.info.name, defaultConfig);
// 2. 验证必需配置
const config = configManager.get(this.info.name);
this.validateRequiredConfig(config);
// 3. 应用环境特定设置
this.applyEnvironmentConfig(configManager);
// 4. 记录配置状态
logger.info('Configuration setup completed', {
port: config.server.port,
corsEnabled: config.server.cors.enabled,
environment: process.env.NODE_ENV || 'development'
});
} catch (error) {
logger.error('Configuration setup failed:', error);
throw error;
}
}
private validateRequiredConfig(config) {
const required = [
'security.jwtSecret',
'server.port'
];
for (const path of required) {
const value = this.getNestedValue(config, path);
if (!value) {
throw new Error(`Required configuration missing: ${path}`);
}
}
}
2. 组件阶段最佳实践
async setupComponents({ serviceRegistry, componentRegistry, configManager, logger }) {
try {
// 1. 按依赖顺序注册服务
await this.registerCoreServices(serviceRegistry, configManager);
await this.registerBusinessServices(serviceRegistry);
await this.registerUIComponents(componentRegistry);
// 2. 验证关键依赖
this.validateCriticalDependencies(serviceRegistry);
// 3. 设置事件处理
this.setupEventHandlers(serviceRegistry);
logger.info('All components registered successfully');
} catch (error) {
logger.error('Component registration failed:', error);
throw error;
}
}
private async registerCoreServices(serviceRegistry, configManager) {
const config = configManager.get(this.info.name);
// 按依赖顺序注册
serviceRegistry.register('ConfigService', new ConfigService(config));
serviceRegistry.register('DatabaseService', new DatabaseService(config.database));
serviceRegistry.register('AuthService', new AuthService(config.security));
}
private validateCriticalDependencies(serviceRegistry) {
const critical = ['DatabaseService', 'AuthService'];
for (const serviceName of critical) {
if (!serviceRegistry.has(serviceName)) {
throw new Error(`Critical service not available: ${serviceName}`);
}
}
}
3. 数据阶段最佳实践
async setupData({ serviceRegistry, logger }) {
const dbService = serviceRegistry.get('DatabaseService');
try {
// 1. 数据库连接测试
await this.testDatabaseConnection(dbService);
// 2. 结构迁移
await this.runSchemaMigrations(dbService, logger);
// 3. 数据迁移
await this.runDataMigrations(dbService, logger);
// 4. 默认数据创建
await this.createDefaultData(dbService, logger);
// 5. 数据完整性检查
await this.validateDataIntegrity(dbService, logger);
logger.info('Data initialization completed successfully');
} catch (error) {
logger.error('Data initialization failed:', error);
// 提供恢复建议
this.provideRecoveryGuidance(error, logger);
throw error;
}
}
private async testDatabaseConnection(dbService) {
try {
await dbService.query('SELECT 1');
} catch (error) {
throw new Error(`Database connection failed: ${error.message}`);
}
}
private provideRecoveryGuidance(error, logger) {
if (error.message.includes('connection')) {
logger.error('Recovery: Check database connection settings and ensure database server is running');
} else if (error.message.includes('permission')) {
logger.error('Recovery: Check database user permissions');
} else if (error.message.includes('migration')) {
logger.error('Recovery: Check migration scripts and database schema');
}
}
错误处理与调试
生命周期错误处理
export class RobustModule implements IEntityModule {
readonly info = { /* ... */ };
async setupConfig({ configManager, logger }) {
try {
// 配置设置逻辑
await this.performConfigSetup(configManager);
} catch (error) {
logger.error('Configuration setup failed:', error);
// 提供默认配置作为回退
this.setupFallbackConfig(configManager, logger);
}
}
async setupComponents({ serviceRegistry, logger }) {
const registrationErrors = [];
// 尝试注册每个组件,收集错误
const components = this.getComponentRegistrations();
for (const component of components) {
try {
await component.register(serviceRegistry);
logger.debug(`Component registered: ${component.name}`);
} catch (error) {
registrationErrors.push({ component: component.name, error });
logger.warn(`Component registration failed: ${component.name}`, error);
}
}
// 检查关键组件是否成功注册
const criticalComponents = ['DatabaseService', 'AuthService'];
const missingCritical = criticalComponents.filter(
name => !serviceRegistry.has(name)
);
if (missingCritical.length > 0) {
throw new Error(`Critical components missing: ${missingCritical.join(', ')}`);
}
if (registrationErrors.length > 0) {
logger.warn(`${registrationErrors.length} non-critical components failed to register`);
}
}
async setupData({ serviceRegistry, logger }) {
const dbService = serviceRegistry.get('DatabaseService');
// 使用事务确保数据一致性
await dbService.transaction(async (trx) => {
try {
await this.runMigrations(trx, logger);
await this.createDefaultData(trx, logger);
logger.info('Data setup completed successfully');
} catch (error) {
logger.error('Data setup failed, rolling back transaction:', error);
throw error; // 事务会自动回滚
}
});
}
}
模块启动监控
// 监控模块启动过程
engine.on('module.config.start', ({ moduleName }) => {
console.log(`⚙️ Configuring ${moduleName}...`);
});
engine.on('module.config.complete', ({ moduleName, duration }) => {
console.log(`✅ ${moduleName} configured in ${duration}ms`);
});
engine.on('module.components.start', ({ moduleName }) => {
console.log(`🔧 Registering ${moduleName} components...`);
});
engine.on('module.components.complete', ({ moduleName, servicesCount, duration }) => {
console.log(`✅ ${moduleName} registered ${servicesCount} services in ${duration}ms`);
});
engine.on('module.data.start', ({ moduleName }) => {
console.log(`📊 Initializing ${moduleName} data...`);
});
engine.on('module.data.complete', ({ moduleName, migrationsRun, duration }) => {
console.log(`✅ ${moduleName} data initialized (${migrationsRun} migrations) in ${duration}ms`);
});
engine.on('module.error', ({ moduleName, phase, error }) => {
console.error(`❌ ${moduleName} failed in ${phase}: ${error.message}`);
});
下一步
了解模块生命周期管理后,继续学习:
Last updated on