JavaScript系列(43)--依赖注入系统实现详解

news/2025/1/31 19:33:19/

JavaScript依赖注入系统实现详解 💉

今天,让我们深入探讨JavaScript的依赖注入系统实现。依赖注入是一种设计模式,它通过将依赖关系的创建和管理从代码中分离出来,提高了代码的可维护性和可测试性。

依赖注入基础概念 🌟

💡 小知识:依赖注入是控制反转(IoC)的一种实现方式,它将对象的创建和依赖关系的处理交给外部容器来管理,而不是在对象内部直接创建依赖对象。

基本实现 📊

javascript">// 1. 基础依赖注入容器
class Container {constructor() {this.services = new Map();this.singletons = new Map();}// 注册服务register(name, definition, dependencies = []) {this.services.set(name, { definition, dependencies });}// 注册单例服务singleton(name, definition, dependencies = []) {this.register(name, definition, dependencies);this.singletons.set(name, null);}// 解析服务resolve(name) {const service = this.services.get(name);if (!service) {throw new Error(`Service ${name} not found`);}// 检查是否是单例且已存在实例if (this.singletons.has(name)) {const singletonInstance = this.singletons.get(name);if (singletonInstance) {return singletonInstance;}}// 解析依赖const dependencies = service.dependencies.map(dep => this.resolve(dep));// 创建实例const instance = typeof service.definition === 'function'? new service.definition(...dependencies): service.definition;// 如果是单例,保存实例if (this.singletons.has(name)) {this.singletons.set(name, instance);}return instance;}
}// 2. 装饰器支持
function Injectable() {return function(target) {// 保存原始构造函数target.injectable = true;return target;};
}function Inject(name) {return function(target, propertyKey) {// 在原型上定义属性const metadata = Reflect.getMetadata('inject', target) || {};metadata[propertyKey] = name;Reflect.defineMetadata('inject', metadata, target);};
}// 3. 依赖解析器
class DependencyResolver {constructor(container) {this.container = container;}// 解析类的依赖resolveClass(target) {const metadata = Reflect.getMetadata('inject', target.prototype);const dependencies = {};if (metadata) {for (const [key, name] of Object.entries(metadata)) {dependencies[key] = this.container.resolve(name);}}return dependencies;}// 创建实例并注入依赖createInstance(target) {const dependencies = this.resolveClass(target);const instance = new target();Object.assign(instance, dependencies);return instance;}
}

高级功能实现 🚀

javascript">// 1. 生命周期管理
class LifecycleManager {constructor() {this.hooks = new Map();}// 注册生命周期钩子registerHook(service, hook) {if (!this.hooks.has(service)) {this.hooks.set(service, []);}this.hooks.get(service).push(hook);}// 执行初始化钩子async initialize(service) {const hooks = this.hooks.get(service) || [];for (const hook of hooks) {if (hook.onInit) {await hook.onInit();}}}// 执行销毁钩子async destroy(service) {const hooks = this.hooks.get(service) || [];for (const hook of hooks) {if (hook.onDestroy) {await hook.onDestroy();}}}
}// 2. 作用域管理
class ScopeManager {constructor() {this.scopes = new Map();this.currentScope = null;}// 创建新作用域createScope(name) {const scope = new Container();this.scopes.set(name, scope);return scope;}// 进入作用域enterScope(name) {const scope = this.scopes.get(name);if (!scope) {throw new Error(`Scope ${name} not found`);}this.currentScope = scope;return scope;}// 退出作用域exitScope() {this.currentScope = null;}// 在当前作用域中解析服务resolve(name) {if (!this.currentScope) {throw new Error('No active scope');}return this.currentScope.resolve(name);}
}// 3. 异步依赖处理
class AsyncContainer extends Container {constructor() {super();this.asyncServices = new Map();}// 注册异步服务async registerAsync(name, factory) {this.asyncServices.set(name, factory);}// 异步解析服务async resolveAsync(name) {// 检查是否是异步服务if (this.asyncServices.has(name)) {const factory = this.asyncServices.get(name);return await factory();}// 否则使用同步解析return this.resolve(name);}// 批量解析异步服务async resolveAll(names) {return Promise.all(names.map(name => this.resolveAsync(name)));}
}

实际应用场景 💼

javascript">// 1. 服务定义和注入
@Injectable()
class UserService {constructor(database) {this.database = database;}async getUsers() {return this.database.query('SELECT * FROM users');}
}@Injectable()
class AuthService {@Inject('userService')userService;async authenticate(username, password) {const user = await this.userService.findByUsername(username);return user && user.password === password;}
}// 2. API服务注入
@Injectable()
class ApiService {constructor(config) {this.baseUrl = config.apiUrl;}async request(method, path, data) {const response = await fetch(`${this.baseUrl}${path}`, {method,headers: {'Content-Type': 'application/json'},body: data ? JSON.stringify(data) : undefined});return response.json();}
}// 3. 业务逻辑注入
@Injectable()
class OrderService {constructor(@Inject('userService') userService,@Inject('paymentService') paymentService,@Inject('notificationService') notificationService) {this.userService = userService;this.paymentService = paymentService;this.notificationService = notificationService;}async createOrder(userId, items) {const user = await this.userService.getUser(userId);const payment = await this.paymentService.processPayment(user, items);if (payment.success) {await this.notificationService.sendOrderConfirmation(user, items);return { success: true, orderId: payment.orderId };}return { success: false, error: payment.error };}
}

性能优化技巧 ⚡

javascript">// 1. 依赖缓存
class CachedContainer extends Container {constructor() {super();this.cache = new Map();}resolve(name) {if (this.cache.has(name)) {return this.cache.get(name);}const instance = super.resolve(name);this.cache.set(name, instance);return instance;}clearCache() {this.cache.clear();}invalidate(name) {this.cache.delete(name);}
}// 2. 延迟加载
class LazyContainer extends Container {constructor() {super();this.factories = new Map();}registerLazy(name, factory) {this.factories.set(name, factory);}resolve(name) {if (this.factories.has(name)) {const factory = this.factories.get(name);const instance = factory();this.register(name, instance);this.factories.delete(name);return instance;}return super.resolve(name);}
}// 3. 批量注册优化
class BatchContainer extends Container {constructor() {super();this.batchQueue = [];}startBatch() {this.batchQueue = [];}register(name, definition, dependencies = []) {this.batchQueue.push({ name, definition, dependencies });}commitBatch() {for (const registration of this.batchQueue) {super.register(registration.name,registration.definition,registration.dependencies);}this.batchQueue = [];}
}

最佳实践建议 💡

  1. 依赖注入模式
javascript">// 1. 构造函数注入
class UserController {constructor(userService, authService) {this.userService = userService;this.authService = authService;}
}// 2. 属性注入
class OrderController {@Inject('orderService')orderService;@Inject('userService')userService;
}// 3. 方法注入
class ProductController {@Inject('productService')setProductService(service) {this.productService = service;}
}

结语 📝

依赖注入是一种强大的设计模式,它能够帮助我们构建更加灵活和可维护的应用。通过本文,我们学习了:

  1. 依赖注入的基本概念和实现
  2. 高级功能如生命周期管理和作用域
  3. 实际应用场景和示例
  4. 性能优化技巧
  5. 最佳实践和设计模式

💡 学习建议:在使用依赖注入时,要注意平衡灵活性和复杂性。不是所有的依赖关系都需要通过注入来管理,要根据实际需求选择合适的方案。


如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻


http://www.ppmy.cn/news/1568221.html

相关文章

TVS选型设计

TVS选型距离 以实际的案例举例。电路的正常工作电压VCC是24V,最高工作电压Vmax是26V,后级电路可承受的最高瞬态电压为50V,实验的测试波形为 8/20μs波形,测试电压500V,测试电源内阻及PPTC的静态电阻合计为2Ω。根据上述信息选择合…

【SpringMVC】——Json数据交互处理

🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大二学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门专栏:🎇【MySQL&#xff0…

用 Scoop 优雅管理 Windows 软件:安装、配置与使用全指南

本篇将主要讲讲如何用「Scoop」优雅管理 Windows 软件:安装、配置与使用全指南 一、Scoop 是什么? Scoop 是一款专为 Windows 设计的命令行软件包管理工具,它能让你像 Linux 系统一样通过命令快速安装、更新和卸载软件。其核心优势包括&…

Jenkins下载 Maven、Allure 插件并且配置环境

文章目录 Jenkins在插件中心下载 maven、allure插件maven插件下载allure插件下载 配置maven、allure 往期推荐: 最新! 在 Linux上搭建Jenkins环境! Jenkins邮件通知的详细配置含邮件通知模板! Jenkin配置企业微信通知 Jenkins在插件中心下载 maven、…

[C语言日寄] <stdio.h> 头文件功能介绍

在C语言的世界里&#xff0c;<stdio.h> 是一个极其重要的头文件&#xff0c;它提供了标准输入输出功能&#xff0c;是C语言程序与用户交互的核心工具。今天&#xff0c;我们就来深入探讨 <stdio.h> 的功能、使用注意事项以及它的拓展应用。 功能介绍 <stdio.h…

Python设计模式 - 组合模式

定义 组合模式&#xff08;Composite Pattern&#xff09; 是一种结构型设计模式&#xff0c;主要意图是将对象组织成树形结构以表示"部分-整体"的层次结构。这种模式能够使客户端统一对待单个对象和组合对象&#xff0c;从而简化了客户端代码。 组合模式有透明组合…

C语言练习(31)

有5个学生&#xff0c;每个学生有3门课程的成绩&#xff0c;从键盘输入以上数据&#xff08;包括学号、姓名、3门课程成绩&#xff09;&#xff0c;计算出平均成绩&#xff0c;将原有数据和计算出的平均分数存放在磁盘文件stud中。 设5名学生的学号、姓名和3门课程成绩如下&am…

android 的aab包

什么是 AAB (Android App Bundle)&#xff1f; AAB (Android App Bundle) 是 Google 推出的新一代 Android 应用发布格式&#xff0c;用于取代传统的 APK 格式。AAB 的全称是 Android App Bundle&#xff0c;扩展名为 .aab&#xff0c;它并不是直接可以安装的文件&#xff0c;…