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. 构造函数注入
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;
}
}
结语 📝
依赖注入是一种强大的设计模式,它能够帮助我们构建更加灵活和可维护的应用。通过本文,我们学习了:
- 依赖注入的基本概念和实现
- 高级功能如生命周期管理和作用域
- 实际应用场景和示例
- 性能优化技巧
- 最佳实践和设计模式
💡 学习建议:在使用依赖注入时,要注意平衡灵活性和复杂性。不是所有的依赖关系都需要通过注入来管理,要根据实际需求选择合适的方案。
如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇
终身学习,共同成长。
咱们下一期见
💻