当前位置: 首页 > article >正文

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

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

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

依赖注入基础概念 🌟

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

基本实现 📊

// 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;
    }
}

高级功能实现 🚀

// 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)));
    }
}

实际应用场景 💼

// 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 };
    }
}

性能优化技巧 ⚡

// 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. 依赖注入模式
// 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.kler.cn/a/519139.html

相关文章:

  • π0:仅有3B数据模型打通Franka等7种机器人形态适配,实现0样本的完全由模型自主控制方法
  • 类和对象(4)——多态:方法重写与动态绑定、向上转型和向下转型、多态的实现条件
  • 2024年度总结(具身智能赛道,欢迎交流)
  • cuda reductionreduce
  • TCP 三次握手四次挥手
  • 网络编程-网络原理HTTP1
  • [极客大挑战 2019]BuyFlag1
  • vue高级组件封装 element组件二次封装
  • Maui学习笔记- SQLite简单使用案例
  • 基于ESP32的桌面小屏幕实战[6]:环境搭建和软件基础
  • 一次StarRocks分析的经历
  • 第25章 测试驱动开发模式深度剖析
  • unity 粒子系统实现碰撞检测(collision)且使粒子不受力
  • tcp/ip协议和ip协议,tcp/ip协议 ip协议
  • 探索JavaScript:网页设计中的创意与实践
  • leetcode——翻转链表(java)
  • (回溯分割)leetcode93 复原IP地址
  • AI学习(vscode+deepseek+cline)
  • INMP441一款微型电容式麦克风(MEMS麦克风)
  • Zookeeper(28)Zookeeper的线性化写入和顺序一致性读是什么?
  • 代码随想录day4
  • 【论文推荐|深度学习,滑坡检测,多光谱影像,自然灾害,遥感】2022年Landslide4Sense竞赛成果:基于多源卫星影像的先进滑坡检测算法研究(一)
  • 手机app如何跳过无障碍权限实现弹框自动点击-ADB连接专题
  • Redis 详解
  • 开源智慧园区管理系统对比五款主流产品探索智能运营新模式
  • PCB布线注意事项(1)