我有一个名为PermissionManager
的类,它在构造函数中接收Voter
接口的列表。
export interface Voter {
vote(): bool;
}
export class PermissionManager {
constructor(private readonly voters: Voter[]) {
}
}
export class SpecificVoter implements Voter {
constructor(private readonly anotherDependency: AnotherDependency) {
}
public function vote(): bool {
return true;
}
}
这个想法是PermissionManager
不应该知道选民是什么。因此,为此,我将每个投票者添加到全局列表中,以便当我实例化PermissionManager
时,它拥有所有投票者的列表。基本上,我正在做一些类似于Symfony的服务标签的事情。
这是我的 NestJS 提供程序:
const provider = {
provide: PermissionManager,
useFactory: (container: ModulesContainer) => {
const voters = [];
globalList.forEach(value => {
container.forEach(module => {
const provider = module.getProviderByKey(value.constructor.name);
if (provider !== undefined) {
voters.push(provider.instance);
}
});
});
return new PermissionManager(voters);
},
inject: [ModulesContainer],
};
提供程序可以正确查找类SpecificVoter
,但它从不实例化其依赖项。
因此,module.getProviderByKey(SpecificVoter).instance
为什么不返回SpecificVoter
及其依赖项?
好的,所以我找到了一种方法来完成这项工作,但它似乎很笨拙。
基本上,似乎提供程序将从.instance
属性返回类实例,而不是依赖项,直到完成某个承诺。因此,我们必须等待该承诺完成才能获得适当的实例。
这是我现在正在做的事情:
{
provide: PermissionManager,
useFactory: (container: ModulesContainer) => {
return new Promise(resolve => {
const promises = [];
const voters = [];
globalList.forEach(value => {
container.forEach(module => {
const provider = module.getProviderByKey(value.constructor.name);
if (provider !== undefined) {
promises.push(new Promise(resolve1 => {
// This following code seems to be a hack for now and should be modified when
// something official replaces it
provider.getInstanceByContextId(STATIC_CONTEXT).donePromise.then(value1 => {
voters.push(provider.instance);
resolve1();
});
}));
}
});
});
Promise.all(promises).then(value => {
resolve(new PermissionManager(voters));
return;
});
});
},
inject: [ModulesContainer],
};