1. 基于参数装饰器的依赖注入机制设计与实现
定义依赖容器
class Container {
private dependencies: Map<string, any> = new Map();
register(key: string, value: any) {
this.dependencies.set(key, value);
}
resolve(key: string) {
return this.dependencies.get(key);
}
}
const container = new Container();
定义参数装饰器
function inject(key: string) {
return function (target: any, propertyKey: string | symbol, parameterIndex: number) {
const originalMethod = target[propertyKey];
target[propertyKey] = function (...args: any[]) {
const dependency = container.resolve(key);
args.splice(parameterIndex, 0, dependency);
return originalMethod.apply(this, args);
};
};
}
使用示例
class Service {
message = 'Hello from Service';
}
class Component {
@inject('Service')
doSomething(service: Service) {
console.log(service.message);
}
}
container.register('Service', new Service());
const component = new Component();
component.doSomething();
2. 与其他设计模式协同工作
与工厂模式协同工作
- 工厂模式作用:工厂模式用于创建对象,在依赖注入场景中,可用于创建复杂对象。例如,如果
Service
对象创建过程复杂,需要特定的初始化参数等,可使用工厂模式。
- 协同方式:修改
Container
的register
方法,使其支持工厂函数注册。
class Container {
private dependencies: Map<string, any> = new Map();
register(key: string, factory: () => any) {
this.dependencies.set(key, factory());
}
resolve(key: string) {
return this.dependencies.get(key);
}
}
- 优势:提高了对象创建的灵活性,使得依赖对象的创建逻辑可以集中管理,增强代码的可维护性和可扩展性。例如,当
Service
对象的创建逻辑发生变化时,只需修改工厂函数,而不会影响到依赖注入的其他部分。
与单例模式协同工作
- 单例模式作用:单例模式确保一个类只有一个实例,并提供全局访问点。在依赖注入中,对于一些需要全局唯一的依赖对象,如数据库连接对象,使用单例模式可避免重复创建,节省资源。
- 协同方式:在
Container
的register
方法中实现单例逻辑。
class Container {
private dependencies: Map<string, any> = new Map();
register(key: string, value: any) {
if (!this.dependencies.has(key)) {
this.dependencies.set(key, value);
}
}
resolve(key: string) {
return this.dependencies.get(key);
}
}
- 优势:保证依赖对象的唯一性,在整个项目中,无论何处需要注入该依赖,都将得到同一个实例。这对于维护全局状态或共享资源的对象非常重要,同时也提高了代码的可维护性,因为开发人员无需担心多个实例可能带来的不一致问题。