使用JavaScript实现一个简单的依赖注入_js架构

使用JavaScript实现一个简单的依赖注入_js架构
最新回答
风微甜

2026-10-29 17:17:51

以下是一个基于 JavaScript 的简单依赖注入(DI)容器实现,包含核心功能解析和代码示例:

一、核心实现原理class Container { constructor() { this.dependencies = {}; // 存储依赖项 } // 注册依赖项 register(name, dependency, singleton = false) { this.dependencies[name] = { factory: typeof dependency === 'function' ? dependency : () => dependency, // 支持值/函数/类 singleton, instance: null }; } // 解析依赖项 resolve(name) { const dep = this.dependencies[name]; if (!dep) throw new Error(`Dependency not found: ${name}`); // 单例模式直接返回实例 if (dep.singleton && dep.instance) { return dep.instance; } // 调用工厂函数并传入容器实例(支持嵌套依赖) const instance = dep.factory(this); // 单例模式缓存实例 if (dep.singleton) { dep.instance = instance; } return instance; } // 清除依赖(测试用) clear(name) { if (name) delete this.dependencies[name]; else this.dependencies = {}; }}二、关键特性说明
  1. 依赖注册

    支持三种形式:值、工厂函数、类

    通过 singleton 参数控制单例模式

  2. 依赖解析

    自动处理嵌套依赖(通过传递容器实例)

    单例模式首次创建后缓存实例

  3. 扩展性

    可通过修改工厂函数支持更复杂的构造逻辑

    容器实例可作为参数传递实现依赖链

三、完整使用示例// 1. 定义基础服务function Logger() { return { log: msg => console.log(`[LOG] ${msg}`) };}// 2. 定义依赖Logger的服务function DataService(container) { const logger = container.resolve('logger'); return { getData: () => { logger.log('Fetching data...'); return ['item1', 'item2']; } };}// 3. 定义嵌套依赖服务function UserService(container) { const dataService = container.resolve('dataService'); return { getUserData: () => dataService.getData() };}// 4. 使用容器const container = new Container();container.register('logger', Logger, true); // 单例Loggercontainer.register('dataService', DataService); // 非单例DataServicecontainer.register('userService', UserService); // 非单例UserService// 5. 解析服务const userService = container.resolve('userService');console.log(userService.getUserData());// 输出:// [LOG] Fetching data...// ['item1', 'item2']四、进阶用法示例// 1. 使用Class定义服务class ApiClient { constructor(logger) { this.logger = logger; } fetch() { this.logger.log('API request sent'); return { success: true }; }}// 2. 注册Class服务(通过工厂函数)container.register('apiClient', (container) => { const logger = container.resolve('logger'); return new ApiClient(logger);}, true);// 3. 使用服务const apiClient = container.resolve('apiClient');console.log(apiClient.fetch());// 输出:// [LOG] API request sent// { success: true }五、设计优势分析
  1. 解耦性:服务间通过容器交互而非直接引用
  2. 可测试性:可轻松替换mock依赖
  3. 灵活性:支持多种服务定义方式
  4. 生命周期控制:通过singleton参数管理实例创建
六、典型应用场景
  1. 大型前端应用的模块管理
  2. 后端服务的中间件组织
  3. 需要频繁替换实现的测试环境
  4. 复杂组件间的依赖协调

这个实现虽然简洁,但包含了DI容器的核心功能。实际项目中可根据需要扩展以下功能:

  • 依赖项参数化配置
  • 生命周期钩子
  • 异步依赖支持
  • 依赖项元数据管理