Dependency injection 如何将依赖项注入与自定义装饰器集成
我正在尝试创建一个需要依赖注入的装饰器。 例如:Dependency injection 如何将依赖项注入与自定义装饰器集成,dependency-injection,nestjs,Dependency Injection,Nestjs,我正在尝试创建一个需要依赖注入的装饰器。 例如: @Injectable() class UserService{ @TimeoutAndCache(1000) async getUser(id:string):Promise<User>{ // Make a call to db to get all Users } } @Injectable() 类用户服务{ @TimeoutAndCache(1000) 异步getUser(id:string):承诺{
@Injectable()
class UserService{
@TimeoutAndCache(1000)
async getUser(id:string):Promise<User>{
// Make a call to db to get all Users
}
}
@Injectable()
类用户服务{
@TimeoutAndCache(1000)
异步getUser(id:string):承诺{
//调用db以获取所有用户
}
}
@TimeoutAndCache返回一个新的承诺,它执行以下操作:
export const TimeoutAndCache=函数timeoutCache(ts:编号,命名空间){
返回函数日志(
目标:目标,,
propertyKey:字符串,
描述符:TypedPropertyDescriptor,
) {
const originalMethod=descriptor.value;//保存对原始方法的引用
descriptor.value=函数(…参数:任意[]){
//前
设timedOut=false;
//运行并存储结果
const result:Promise=originalMethod.apply(这是args);
const task=新承诺((解决、拒绝)=>{
常量计时器=设置超时(()=>{
如果(!timedOut){
timedOut=true;
console.log('完成前超时');
拒绝(“timedout”);
}
},ts);
结果。然后(res=>{
if(timedOut){
//存储在缓存中
log(“存储在缓存中”);
}否则{
清除超时(计时器);
//返回结果
决议(res);
}
});
});
返回任务;
};
返回描述符;
};
};
我需要注入一个RedisService来保存计算结果。
有一种方法可以将Redis服务注入到UserService中,但看起来有点难看 > P>你应该考虑使用<代码>拦截器< /C>而不是自定义装饰器,因为它们在嵌套管道中运行较早,默认支持依赖注入。p> 但是,由于既要传递值(缓存超时)又要解决依赖关系,因此必须使用
mixin
模式
导入{
执行上下文,
可注射,
米辛,
内斯特拦截器,
}来自“@nestjs/common”;
从“rxjs”导入{Observable};
从“./test/test.service”导入{TestService};
@可注射()
导出抽象类CacheInterceptor实现NestInterceptor{
受保护的摘要只读缓存持续时间:number;
构造函数(私有只读testService:testService){}
拦截(
上下文:ExecutionContext,
调用$:可观察,
):可见{
//不管你的逻辑是什么
回电$;
}
}
导出常量makeCacheInterceptor=(cacheDuration:number)=>
混合(
//tslint:禁用下一行:每个文件的最大类数
类扩展了CacheInterceptor{
受保护的只读cacheDuration=cacheDuration;
},
);
然后,您将能够以类似的方式将拦截器应用于处理程序:
@Injectable()
类用户服务{
@UseInterceptors(makeCacheInterceptor(1000))
异步getUser(id:string):承诺{
//调用db以获取所有用户
}
}
我很难让拦截器工作,即使是上的简单日志拦截器也不能在类中的任何方法上工作。它似乎只对@Controller注释的方法有效?您能为这个添加一个测试用例吗?@jesse carter您从哪里了解到了mixin
函数?我没有在文档中看到过()
export const TimeoutAndCache = function timeoutCache(ts: number, namespace) {
return function log(
target: object,
propertyKey: string,
descriptor: TypedPropertyDescriptor<any>,
) {
const originalMethod = descriptor.value; // save a reference to the original method
descriptor.value = function(...args: any[]) {
// pre
let timedOut = false;
// run and store result
const result: Promise<object> = originalMethod.apply(this, args);
const task = new Promise((resolve, reject) => {
const timer = setTimeout(() => {
if (!timedOut) {
timedOut = true;
console.log('timed out before finishing');
reject('timedout');
}
}, ts);
result.then(res => {
if (timedOut) {
// store in cache
console.log('store in cache');
} else {
clearTimeout(timer);
// return the result
resolve(res);
}
});
});
return task;
};
return descriptor;
};
};