依赖注入(DI)/控制反转(IoC) nodejs案例详解
前置知识
Reflect API
官方文档:reflect-metadata
举个例子介绍常用的 API:
@Reflect.metadata('key', 'value')
class Person {name: string;constructor(public age: number) {}
}Reflect.getMetadata('design:type', Person.prototype, 'name');
// 作用:获取元数据键对应的元数据值,design:type表示参数类型
// 输出: [Function: String]
// 参数:(元数据键, 类构造函数/对象, 属性名【可选】)Reflect.defineMetadata('custom:tag', 'VIP', Person.prototype, 'name');
console.log(Reflect.getMetadata('custom:tag', Person.prototype, 'name'));
// 作用:定义元数据键对应的元数据值
// 输出: VIP
// 参数:(元数据键, 值, 类构造函数/对象, 属性名【可选】)Reflect.getOwnMetadataKeys(Person.prototype, 'name');
// 作用:获取元数据键
// 输出: ['design:type', 'custom:tag']
// 参数:(类构造函数/对象, 属性名【可选】)
装饰器
类装饰器
//添加日志打印
function Log(){return function (target) {return class extends target {constructor(...args) {console.log('log')super(...args)}}}
}
//修改构造函数,实现单例模式
function Singleton() {return function (target) {return class extends target {private static instance: any;constructor(...args: any[]) {if (Singleton.instance) {return Singleton.instance;}super(...args);Singleton.instance = this;}};};
}@Log()
@Singleton()
class Database {constructor(private connectionString: string) {}
}
const db1 = new Database("db://localhost"); // 打印log
const db2 = new Database("db://localhost/another"); // 打印log
console.log(db1 === db2); // true
方法装饰器
// 权限验证装饰器
function Authenticated() {// 参数:target: 类的原型,propertyKey: 方法名,descriptor: 方法描述符,包含get/set/value/writable/configurable等属性return function (target, propertyKey, descriptor) {const originalMethod =