8000 GitHub - Koatty/koatty_container: The implementation of IOC container in Typescript, supports DI (Dependency Injection) and AOP (Aspect Programming).
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

The implementation of IOC container in Typescript, supports DI (Dependency Injection) and AOP (Aspect Programming).

License

Notifications You must be signed in to change notification settings

Koatty/koatty_container

Repository files navigation

koatty_container Version npm npm Downloads GitHub stars

🏆 TypeScript IOC 容器 + 装饰器管理系统

专为现代 Node.js 应用设计的完整解决方案,提供智能循环依赖处理、高性能缓存优化、完整的 AOP 支持,以及自定义装饰器管理能力

🌟 核心亮点

  • 🎯 自定义装饰器支持 - 强大的装饰器管理器,轻松扩展您的装饰器生态
  • 100% 测试通过 - 141个测试,完整代码覆盖率
  • 🚀 高性能缓存 - WeakMap + LRU策略,极速启动和运行
  • 💾 智能内存管理 - 自动优化,防止内存泄漏
  • 🔗 智能循环依赖处理 - 优雅解决复杂依赖关系
  • 🎯 完整 AOP 支持 - Before/After/Around 切面编程
  • 💉 多种注入方式 - 构造函数、属性、字符串标识符
  • 📋 完整 TypeScript - 类型安全,智能提示

📦 安装

npm install koatty_container
#
yarn add koatty_container
#
pnpm add koatty_container

🚀 IOC容器功能

基础依赖注入

import { IOC, Autowired, Component, Service } from "koatty_container";

@Component()
class UserRepository {
  async findById(id: string) {
    return { id, name: "John Doe", email: "john@example.com" };
  }
}

@Service()
class UserService {
  @Autowired()
  private userRepository: UserRepository;

  async getUser(id: string) {
    return await this.userRepository.findById(id);
  }
}

@Component()
class UserController {
  @Autowired()
  private userService: UserService;

  async handleRequest(id: string) {
    const user = await this.userService.getUser(id);
    return { success: true, data: user };
  }
}

// 注册组件
IOC.reg(UserRepository);
IOC.reg(UserService);
IOC.reg(UserController);

// 使用
const controller
9E7A
 = IOC.get(UserController);
const result = await controller.handleRequest("123");

高性能批量注册

async function initializeApp() {
  const components = [
    { target: UserRepository },
    { target: UserService },
    { target: UserController },
    { target: EmailService },
    { target: OrderService }
  ];

  // 批量注册 + 性能优化
  IOC.batchRegister(components, {
    preProcessDependencies: true,  // 预处理依赖关系
    warmupAOP: true               // 预热 AOP 缓存
  });

  // 性能统计
  const stats = IOC.getDetailedPerformanceStats();
  console.log(`🚀 初始化完成:`);
  console.log(`   - 组件数量: ${stats.containers.totalRegistered}`);
  console.log(`   - 依赖缓存命中率: ${(stats.lruCaches.dependencies.hitRate * 100).toFixed(1)}%`);
  console.log(`   - AOP 缓存命中率: ${(stats.lruCaches.aop.hitRates.overall * 100).toFixed(1)}%`);
}

await initializeApp();

🎯 AOP 面向切面编程

方法拦截

@Aspect()
export class LoggingAspect implements IAspect {
  async run(args: any[], target?: any, options?: any): Promise<any> {
    console.log(`🔍 调用 ${options?.targetMethod}`, args);
    return Promise.resolve();
  }
}

@Component()
class OrderService {
  @Before(LoggingAspect, { level: 'info' })
  async createOrder(orderData: any) {
    return { orderId: Date.now(), ...orderData };
  }
}

环绕通知 (Around)

@Aspect()
class TransactionAspect {
  async run(args: any[], proceed: Function, options?: any): Promise<any> {
    console.log(`🔄 开始事务: ${options?.targetMethod}`);
    
    try {
      const result = await proceed(args);
      console.log(`✅ 提交事务: ${options?.targetMethod}`);
      return {
        ...result,
        transactionStatus: 'committed',
        timestamp: new Date().toISOString()
      };
    } catch (error) {
      console.log(`❌ 回滚事务: ${options?.targetMethod}`, error);
      throw error;
    }
  }
}

@Component()
class UserService {
  @Around(TransactionAspect, { timeout: 5000 })
  async createUser(userData: any) {
    return { id: Date.now(), ...userData };
  }
}

🎨 自定义装饰器详解

1. 方法装饰器 - 增强方法行为

import { decoratorManager } from 'koatty_container';

// 1️⃣ 定义装饰器逻辑
const timingWrapper = (originalMethod: Function, config: any, methodName: string) => {
  return function (this: any, ...args: any[]) {
    const start = Date.now();
    console.log(`⏱️ 开始执行 ${methodName}`);
    
    const result = originalMethod.apply(this, args);
    
    const duration = Date.now() - start;
    console.log(`✅ ${methodName} 执行完成,耗时 ${duration}ms`);
    
    return result;
  };
};

// 2️⃣ 注册装饰器
decoratorManager.method.registerWrapper('timing', timingWrapper);

// 3️⃣ 创建装饰器函数
function Timing(enabled: boolean = true) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    return decoratorManager.method.registerDecorator(target, propertyKey, {
      type: 'timing',
      config: { enabled },
      applied: false,
      priority: 5 // 优先级控制
    }, descriptor);
  };
}

// 4️⃣ 使用自定义装饰器
class UserService {
  @Timing()
  async createUser(userData: any) {
    // 模拟数据库操作
    await new Promise(resolve => setTimeout(resolve, 100));
    return { id: Date.now(), ...userData };
  }
  
  @Timing(false) // 禁用计时
  async getUser(id: string) {
    return { id, name: "John Doe" };
  }
}

2. 缓存装饰器 - 智能结果缓存

// 高级缓存装饰器示例
const cacheWrapper = (originalMethod: Function, config: any, methodName: string) => {
  const cache = new Map();
  
  return function (this: any, ...args: any[]) {
    const cacheKey = config.keyGenerator ? 
      config.keyGenerator(args) : 
      JSON.stringify(args);
    
    // 检查缓存
    if (cache.has(cacheKey)) {
      console.log(`🎯 缓存命中: ${methodName}`);
      return cache.get(cacheKey);
    }
    
    // 执行原方法
    const result = originalMethod.apply(this, args);
    
    // 异步结果处理
    if (result instanceof Promise) {
      return result.then(asyncResult => {
        cache.set(cacheKey, asyncResult);
        console.log(`💾 缓存存储: ${methodName}`);
        
        // TTL支持
        if (config.ttl) {
          setTimeout(() => cache.delete(cacheKey), config.ttl * 1000);
        }
        
        return asyncResult;
      });
    }
    
    // 同步结果缓存
    cache.set(cacheKey, result);
    return result;
  };
};

decoratorManager.method.registerWrapper('cache', cacheWrapper);

function Cache(ttl?: number, keyGenerator?: (args: any[]) => string) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    return decoratorManager.method.registerDecorator(target, propertyKey, {
      type: 'cache',
      config: { ttl, keyGenerator },
      applied: false,
      priority: 10 // 高优先级,优先执行
    }, descriptor);
  };
}

// 使用缓存装饰器
class DataService {
  @Cache(300, (args) => `user:${args[0]}`) // 5分钟TTL,自定义key
  async getUserProfile(userId: string) {
    console.log(`📡 从数据库加载用户: ${userId}`);
    // 模拟数据库查询
    await new Promise(resolve => setTimeout(resolve, 200));
    return { id: userId, name: "John", email: "john@example.com" };
  }
}

3. 属性装饰器 - 属性行为增强

// 属性验证装饰器
const validateWrapper = (originalDescriptor: PropertyDescriptor | undefined, config: any, propertyName: string) => {
  return {
    get: function () {
      const privateKey = `_${propertyName}`;
      if (!(privateKey in this)) {
        // 设置默认值
        (this as any)[privateKey] = config.defaultValue;
      }
      return (this as any)[privateKey];
    },
    
    set: function (value: any) {
      // 类型验证
      if (config.type && typeof value !== config.type) {
        throw new Error(`属性 ${propertyName} 必须是 ${config.type} 类型`);
      }
      
      // 自定义验证器
      if (config.validators) {
        for (const validator of config.validators) {
          if (!validator.fn(value)) {
            throw new Error(`属性 ${propertyName} 验证失败: ${validator.message}`);
          }
        }
      }
      
      console.log(`✅ 属性 ${propertyName} 设置为:`, value);
      (this as any)[`_${propertyName}`] = value;
    },
    
    enumerable: true,
    configurable: true
  };
};

decoratorManager.property.registerWrapper('validate', validateWrapper);

function Validate(
  type?: string, 
  validators?: Array<{ fn: (value: any) => boolean; message: string }>,
  defaultValue?: any
) {
  return function (target: any, propertyKey: string) {
    return decoratorManager.property.registerDecorator(target, propertyKey, {
      wrapperTypes: ['validate'],
      config: { type, validators, defaultValue }
    });
  };
}

// 使用属性装饰器
class User {
  @Validate('string', [
    { fn: (v: string) => v.length > 0, message: '姓名不能为空' },
    { fn: (v: string) => v.length < 50, message: '姓名长度不能超过50' }
  ], 'Anonymous')
  name: string;

  @Validate('number', [
    { fn: (v: number) => v >= 0, message: '年龄必须大于等于0' },
    { fn: (v: number) => v <= 150, message: '年龄必须小于等于150' }
  ], 0)
  age: number;
}

// 使用示例
const user = new User();
console.log(user.name); // "Anonymous" (默认值)
user.age = 25; // ✅ 验证通过
// user.age = -5; // ❌ 抛出错误: 年龄必须大于等于0

4. 类装饰器 - 类级别增强

// 依赖注入装饰器
const injectWrapper = (originalClass: Function, config: any) => {
  return class extends (originalClass as any) {
    constructor(...args: any[]) {
      super(...args);
      
      // 自动注入依赖
      for (const [key, dependency] of Object.entries(config.dependencies)) {
        (this as any)[key] = dependency;
      }
      
      console.log(`🔌 已为 ${originalClass.name} 注入依赖:`, Object.keys(config.dependencies));
    }
  };
};

decoratorManager.class.registerWrapper('inject', injectWrapper);

function Injectable(dependencies: Record<string, any>) {
  return function (target: Function) {
    return decoratorManager.class.registerDecorator(target, {
      type: 'inject',
      config: { dependencies },
      applied: false,
      priority: 1
    });
  };
}

// 使用类装饰器
@Injectable({
  logger: { log: (msg: string) => console.log(`[LOG] ${msg}`) },
  config: { apiUrl: 'https://api.example.com', timeout: 5000 }
})
class ApiService {
  private logger: any;
  private config: any;
  
  async fetchData(endpoint: string) {
    this.logger.log(`正在请求: ${this.config.apiUrl}${endpoint}`);
    // API调用逻辑
    return { data: 'success' };
  }
}

🔥 高级特性

1. 装饰器组合与优先级

class OrderService {
  @Timing()           // 优先级: 5
  @Cache(600)         // 优先级: 10 (先执行)
  @RateLimit(100)     // 优先级: 15 (最先执行)
  async processOrder(orderData: any) {
    // 执行顺序: RateLimit -> Cache -> Timing -> 原方法
    return { orderId: Date.now(), ...orderData };
  }
}

2. 条件装饰器

function ConditionalCache(condition: () => boolean, ttl: number = 300) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    if (!condition()) {
      return descriptor; // 条件不满足,不应用装饰器
    }
    
    return decoratorManager.method.registerDecorator(target, propertyKey, {
      type: 'cache',
      config: { ttl },
      applied: false,
      priority: 8
    }, descriptor);
  };
}

class ProductService {
  @ConditionalCache(() => process.env.NODE_ENV === 'production', 600)
  async getProductList() {
    // 只在生产环境启用缓存
    return await this.fetchProducts();
  }
}

3. 装饰器统计与监控

// 获取装饰器使用统计
const stats = decoratorManager.getComprehensiveStats();

console.log('📊 装饰器统计信息:');
console.log(`  方法装饰器: ${stats.method.decoratedMethods}个`);
console.log(`  类装饰器: ${stats.class.decoratedClasses}个`);
console.log(`  属性装饰器: ${stats.property.decoratedProperties}个`);
console.log(`  缓存命中率: ${stats.method.cacheStats.hitRate}%`);
console.log(`  注册的装饰器类型: ${stats.method.registeredTypes.join(', ')}`);

// 性能监控
const performance = decoratorManager.getPerformanceMetrics();
console.log('⚡ 性能指标:');
console.log(`  平均执行时间: ${performance.averageExecutionTime}ms`);
console.log(`  内存使用: ${performance.memoryUsage}MB`);

📊 性能数据

⚡ 性能指标

  • 装饰器注册: < 1ms
  • 依赖注入: < 5ms
  • AOP拦截开销: < 0.1ms
  • 缓存命中率: > 90%
  • 内存使用: 优化到最小

📈 规模支持

  • 组件数量: 支持10,000+组件
  • 装饰器链: 支持50+装饰器组合
  • 并发请求: 支持高并发场景
  • 内存管理: 自动垃圾回收优化

🛠️ API参考

DecoratorManager 核心API

interface DecoratorManager {
  // 方法装饰器管理器
  method: {
    registerWrapper(type: string, wrapper: MethodWrapperFunction): void;
    registerDecorator(target: any, propertyKey: string, metadata: DecoratorMetadata, descriptor: PropertyDescriptor): PropertyDescriptor;
    unregisterWrapper(type: string): boolean;
    hasWrapper(type: string): boolean;
    getRegisteredTypes(): string[];
    clearCache(): void;
    getCacheStats(): CacheStats;
  };
  
  // 类装饰器管理器
  class: {
    registerWrapper(type: string, wrapper: ClassWrapperFunction): void;
    registerDecorator(target: Function, metadata: DecoratorMetadata): Function;
    trackInstance(instance: any): void;
    getDecoratedClasses(): Function[];
  };
  
  // 属性装饰器管理器
  property: {
    registerWrapper(type: string, wrapper: PropertyWrapperFunction): void;
    registerDecorator(target: any, propertyKey: string, metadata: PropertyDecoratorMetadata): PropertyDescriptor;
    getPropertyWrapper(target: any, propertyKey: string): PropertyWrapper | undefined;
    getDecoratedProperties(): Array<{ target: any; propertyKey: string; metadata: PropertyDecoratorMetadata }>;
  };
  
  // 统一管理
  clearAllCaches(): void;
  getComprehensiveStats(): ComprehensiveStats;
  hasWrapper(type: string): boolean;
  getAllRegisteredTypes(): { method: string[]; class: string[]; property: string[] };
}

🌟 实战案例

// 1. 定义自定义装饰器
@Injectable({ database: new DatabaseConnection(), logger: new Logger() })
class UserService {
  @Cache(300)
  @Timing()
  @RateLimit(1
92AD
00, 60) // 每分钟100次请求
  async getUser(@Validate('string') userId: string) {
    return await this.database.findUser(userId);
  }
  
  @Transaction({ isolationLevel: 'READ_COMMITTED' })
  @Audit('USER_CREATION', { includeDetails: true })
  async createUser(@Validate('object') userData: UserData) {
    return await this.database.createUser(userData);
  }
}

// 2. 属性验证
class UserProfile {
  @Validate('string', [
    { fn: (v) => v.length > 0, message: '用户名不能为空' },
    { fn: (v) => /^[a-zA-Z0-9_]+$/.test(v), message: '用户名只能包含字母、数字和下划线' }
  ])
  username: string;
  
  @Validate('string', [
    { fn: (v) => /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(v), message: '邮箱格式不正确' }
  ])
  email: string;
  
  @Validate('number', [
    { fn: (v) => v >= 18, message: '年龄必须大于等于18岁' }
  ], 18)
  age: number;
}

// 3. 使用系统
const userService = IOC.get(UserService);
const user = await userService.getUser('123'); // 自动缓存、计时、限流

const profile = new UserProfile();
profile.username = 'john_doe';    // ✅ 验证通过
profile.email = 'john@example.com'; // ✅ 验证通过
// profile.age = 15;              // ❌ 验证失败

📄 许可证

BSD-3 License - 详见 LICENSE 文件

🔗 相关链接


⭐ 如果这个项目对您有帮助,请给我们一个 Star!

About

The implementation of IOC container in Typescript, supports DI (Dependency Injection) and AOP (Aspect Programming).

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  
0