如何将依赖项注入与自定义装饰器集成

时间:2019-01-21 03:06:53

标签: dependency-injection nestjs

我正在尝试创建一个需要依赖项注入的装饰器。 例如:

@Injectable()
class UserService{
  @TimeoutAndCache(1000)
  async getUser(id:string):Promise<User>{
     // Make a call to db to get all Users
  }
}

@TimeoutAndCache返回一个新的诺言,该诺言将执行以下操作:

  1. 如果调用花费的时间超过1000ms,则返回拒绝,并在调用完成后将其存储到redis(以便下次可以提取)。
  2. 如果通话时间少于1000ms,只需返回结果
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;
  };
};

我需要注入RedisService来保存评估结果。 我可以将Redis Service注入UserService的一种方法,但是看起来很丑陋。

1 个答案:

答案 0 :(得分:0)

您应该考虑使用sort而不是自定义装饰器,因为它们在Nest管道中较早运行,并且默认情况下支持依赖项注入。

但是,因为您既要传递值(用于缓存超时),又要解析依赖关系,所以必须使用$orderby模式。

Interceptor

然后,您将能够以类似的方式将拦截器应用于您的处理程序:

mixin