首先实现一个简易IoC容器,通过bind、singleton和resolve方法管理依赖;利用$inject声明构造函数依赖,实现自动注入;支持类、工厂函数和值绑定,提升灵活性。

依赖注入(Dependency Injection, DI)和控制反转(Inversion of Control, IoC)是现代软件设计中解耦组件、提升可测试性和可维护性的关键模式。在JavaScript中,虽然语言本身不内置DI机制,但通过手动实现或使用轻量容器,可以很好地支持这一思想。本文将带你从零开始设计并实现一个简易但实用的IoC容器。
控制反转是指将对象创建和依赖管理的责任从类内部转移到外部容器。依赖注入是实现IoC的一种方式,即通过构造函数、方法或属性将依赖“注入”到目标对象中,而不是在类内部直接实例化。
例如,一个服务类不需要自己创建数据库连接,而是由外部传入:
class UserService {
constructor(userRepository) {
this.userRepository = userRepository;
}
getUser(id) {
return this.userRepository.findById(id);
}
}
这样,UserService不再关心UserRepository如何创建,只依赖其接口行为,实现了松耦合。
立即学习“Java免费学习笔记(深入)”;
IoC容器的核心职责是:注册依赖、解析依赖、管理生命周期。我们可以设计一个Container类来实现这些功能。
基本能力包括:
我们通过构造函数参数的类型提示(或手动标记)来实现自动依赖解析。
JavaScript不支持运行时类型反射,但我们可以通过一些约定来模拟。常见做法是使用$inject静态属性或装饰器来声明依赖。
示例实现:
class Container {
constructor() {
this.bindings = new Map();
this.singletons = new Map();
}
bind(token, implementation) {
this.bindings.set(token, { implementation, singleton: false });
}
singleton(token, implementation) {
this.bindings.set(token, { implementation, singleton: true });
}
resolve(token) {
if (this.singletons.has(token)) {
return this.singletons.get(token);
}
const binding = this.bindings.get(token);
if (!binding) {
throw new Error(`No binding found for ${token.name || token}`);
}
const { implementation, singleton } = binding;
const dependencies = implementation.$inject || [];
const instances = dependencies.map(dep => this.resolve(dep));
const instance = new implementation(...instances);
if (singleton) {
this.singletons.set(token, instance);
}
return instance;
}
}
使用方式:
class UserRepository { }
UserRepository.$inject = [];
class UserService {
constructor(userRepository) {
this.userRepository = userRepository;
}
}
UserService.$inject = [UserRepository];
const container = new Container();
container.bind(UserRepository, UserRepository);
container.bind(UserService, UserService);
const userService = container.resolve(UserService);
除了类,容器还应支持值绑定和工厂函数,以满足不同场景。
扩展bind方法:
bindValue(token, value) {
this.bindings.set(token, {
implementation: () => value,
singleton: true
});
}
bindFactory(token, factoryFn) {
this.bindings.set(token, {
implementation: factoryFn,
singleton: false
});
}
这样可以注入配置、API客户端等非类实例。
基本上就这些。一个轻量的IoC容器不需要复杂的设计,关键是清晰的API和可靠的依赖解析。你可以在此基础上增加作用域、异步加载、模块化注册等功能。核心思想是:让对象专注于行为,把创建交给容器。
以上就是JavaScript依赖注入_IoC容器设计与实现的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号