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

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. 最佳实践和设计模式

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


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

终身学习,共同成长。

咱们下一期见

💻

相关推荐
还是大剑师兰特26 分钟前
TypeScript 面试题及详细答案 100题 (91-100)-- 工程实践与框架集成
前端·javascript·typescript·1024程序员节
可触的未来,发芽的智生32 分钟前
触摸未来2025-10-25:蓝图绘制
javascript·python·神经网络·程序人生·自然语言处理
用户479492835691532 分钟前
typeof null === 'object':JavaScript 最古老的 bug 为何 30 年无法修复?
前端·javascript·面试
golang学习记32 分钟前
Go slog 日志打印最佳实践指南
开发语言·后端·golang
新手村领路人43 分钟前
python opencv gpu加速 cmake msvc cuda编译问题和设置
开发语言·python·opencv
非凡ghost1 小时前
By Click Downloader(下载各种在线视频) 多语便携版
前端·javascript·后端
非凡ghost1 小时前
VisualBoyAdvance-M(GBA模拟器) 中文绿色版
前端·javascript·后端
dengzhenyue1 小时前
C# 初级编程
开发语言·c#
非凡ghost1 小时前
K-Lite Mega/FULL Codec Pack(视频解码器)
前端·javascript·后端
麦麦大数据1 小时前
F034 vue+neo4j 体育知识图谱系统|体育文献知识图谱vue+flask知识图谱管理+d3.js可视化
javascript·vue.js·知识图谱·neo4j·文献·体育·知识图谱管理