装饰器在任何其他混乱“this”上下文之前调用方法

真正的问题

我想我找到了真正的问题,inversify其他一切都很好。在原来的帖子中,我省略了部分代码,因为我认为它们不是造成问题的原因。


在我的ICitiesRepo实现中,我有一个方法ensureDb确保初始化一些typeorm属性,因为这个方法必须是异步的,我不能只在构造函数中调用它,所以应该在任何 CRUD 操作之前调用它,然后我创建了一个具有以下目的的装饰器ensureDb在类中的任何其他方法之前调用:


  export const ensureCall = (method: string) => {

    return (target: any) => {

      for (const prop of Object.getOwnPropertyNames(target.prototype)) {

        if (prop === method || prop === 'constructor') continue;


        const originalMethod = target.prototype[prop];

        if (originalMethod instanceof Function) {

          target.prototype[prop] = async (...args: any[]) => {

            await target.prototype[method]();

            return originalMethod.apply(this, args);

          };

        }

      }

    };

  };

这就是用途:


   @ensureCall('ensureDb')

   @injectable()

   class CitiesRepo implements ICitiesRepo {

       @inject('CitiesWriteRepo') private readonly repo: IWriteRepo<City>;

       

       async ensureDb() {

          await this.repo.doSomething();

          // repo is undefined because I messed up with the context

       }

   

       // interface implementation

   }

ensureDb如果我删除该装饰器并在其他方法之前调用它就可以工作:


   const container = getContainer();

   const citiesRepo: ICitiesRepo = container.get('CitiesRepo');

   await citiesRepo.ensureDb();

   const list = await citiesRepo.getAll(); // It works

是否有可能解决这个问题或其他更好的方法来实现我想做的事情?


原帖

我有一个带有通用存储库的项目,但在使用 inversifyJS 注入存储库对象时遇到一些问题。结构是这样的:


   interface IWriteRepo<T>  { /* interface members */ }


   @injectable()

   class WriteRepo<City> implements IWriteRepo<City> { /* interface implementation */ }


   interface ICitiesRepo { /* interface members */ }


   @injectable()

   class CitiesRepo implements ICitiesRepo {

       @inject('CitiesWriteRepo') private readonly repo: IWriteRepo<City>;


       // interface implementation

   }


该服务已正确注入,repo: ICitiesRepo但通用“孙子”repo: IWriteRepo<City>未定义。


知道如何修复它吗?


天涯尽头无女友
浏览 83回答 1
1回答

紫衣仙女

你快到了。你之所以得到这个,是undefined因为this你的装饰器中是未定义的,应该引用你的目标的实例化实例。将该定义更改为常规函数调用而不是箭头函数应该可以解决问题。export const ensureCall = (method: string) => {&nbsp; return (target: any) => {&nbsp; &nbsp; for (const prop of Object.getOwnPropertyNames(target.prototype)) {&nbsp; &nbsp; &nbsp; if (prop === method || prop === 'constructor') continue;&nbsp; &nbsp; &nbsp; const originalMethod = target.prototype[prop];&nbsp; &nbsp; &nbsp; if (originalMethod instanceof Function) {&nbsp; &nbsp; &nbsp; &nbsp; // Regular function declaration&nbsp; &nbsp; &nbsp; &nbsp; target.prototype[prop] = async function(...args: any[]) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await target.prototype[method]();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Now `this` refers to an instantiated instance&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return originalMethod.apply(this, args);&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; };};
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript