gpt4 book ai didi

javascript - 装饰器在任何其他困惑与 "this"上下文之前调用方法

转载 作者:行者123 更新时间:2023-12-03 07:10:01 25 4
gpt4 key购买 nike

真正的问题

我想我找到了真正的问题,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 注入(inject)存储库对象时遇到了一些问题。结构是这样的:

   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
}

interface ICitiesService { /* interface members */ }

@injeactable()
class CitiesService {
@inject('CitiesRepo') repo: ICitiesRepo;

// interface implementation
}

// binding
const container = new Container();
container.bind<IWriteRepo<City>>('CitiesWriteRepo').to(WriteRepo);
container.bind<ICitiesRepo>('CitiesRepo').to(CitiesRepo);
container.bind<ICitiesService>('CitiesService').to(CitiesService);

我正在使用节点应用程序测试代码,当我尝试获取通用存储库 ( IWriteRepo<City> ) 和 CitiesRepo 时我没有任何问题:

   const container = getContainer();
const citiesRepo: ICitiesRepo = container.get('CitiesRepo'); // OK and prop repo injected correctly
const citiesWriteRepo: IWriteRepo<City> = container.get('CitiesWriteRepo'); // OK

当我尝试获取服务时出现问题:

   const container = getContainer();
const citiesService: ICitiesService = container.get('CitiesService');

服务被正确注入(inject)并且也是repo: ICitiesRepo但是通用的“孙子”repo: IWriteRepo<City>未定义。

知道如何解决吗?

编辑

我仍在努力找出问题所在。现在我尝试将类注入(inject)构造函数,但发生了一些奇怪的事情:InversifyJS 正确注入(inject)了依赖项,我将其分配给属性,但当我尝试使用它时它是未定义的。

   interface ICitiesRepo { /* interface members */ }

@injectable()
class CitiesRepo implements ICitiesRepo {
private readonly repo: IWriteRepo<City>;

constructor(@inject('CitiesWriteRepo') repo: IWriteRepo<City>) {
console.log(repo); // result: WriteRepo {}
this.repo = repo;
console.log(this.repo); // result: WriteRepo {}
}

getAll() {
console.log(this.repo); // result: undefined
}

// interface implementation
}

最佳答案

差不多了。你得到 undefined 因为你的装饰器中的 this 是未定义的并且应该引用你的目标的实例化实例。将该定义更改为常规函数调用而不是箭头函数应该可以解决问题。

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) {
// Regular function declaration
target.prototype[prop] = async function(...args: any[]) {
await target.prototype[method]();
// Now `this` refers to an instantiated instance
return originalMethod.apply(this, args);
};
}
}
};
};

关于javascript - 装饰器在任何其他困惑与 "this"上下文之前调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64683100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com