代码示例
// 定义服务类
class ServiceA {
public doSomething() {
return 'ServiceA is doing something';
}
}
class ServiceB {
public doAnotherThing() {
return 'ServiceB is doing another thing';
}
}
// 依赖注入装饰器
function injectServices(...services: any[]) {
return function (target: any) {
for (let i = 0; i < services.length; i++) {
const service = new services[i]();
Object.defineProperty(target.prototype, services[i].name, {
value: service,
enumerable: true,
writable: true,
configurable: true
});
}
};
}
// App类使用依赖注入装饰器
@injectServices(ServiceA, ServiceB)
class App {
private serviceA: ServiceA;
private serviceB: ServiceB;
constructor() {
// 这里不需要手动实例化ServiceA和ServiceB,装饰器已经注入
}
public run() {
console.log(this.serviceA.doSomething());
console.log(this.serviceB.doAnotherThing());
}
}
// 使用App类
const app = new App();
app.run();
设计思路
- 定义服务类:首先定义
ServiceA
和ServiceB
两个服务类,它们各自有自己的功能方法。
- 创建依赖注入装饰器:
injectServices
装饰器接收多个服务类作为参数。在装饰器内部,遍历传入的服务类,创建每个服务类的实例,并通过Object.defineProperty
将实例添加到目标类(App
类)的原型上,这样目标类的实例就可以访问到这些注入的服务实例。
- 应用装饰器:在
App
类上使用@injectServices(ServiceA, ServiceB)
装饰器,这样在App
类实例化时,ServiceA
和ServiceB
的实例就会被注入到App
类实例中。
- 使用注入的服务:
App
类的run
方法中可以直接使用注入的serviceA
和serviceB
实例调用其方法,完成依赖的功能。这种设计方式保证了装饰器的复用性和灵活性,只需要在需要依赖注入的类上使用装饰器并传入相应的服务类即可。