我想知道是否有一种方法可以访问NestJS中的DI注入器并将其直接用于实例化类。这类似于Angular或Inversify在特殊情况下直接暴露喷油器的方式。
多提供商将解决我的用例。但是,尽管直到NestJS支持多提供者,我仍在尝试创建一个将多个防护作为一个安全防护组合在一起的复合防护,以便我可以全局应用需要访问DI的多个防护。我希望复合防护仅接收类型的数组,然后使用注入器来填充这些类型的对象。
我尝试将Injector
指定为工厂依赖项,但Nest无法解决。如果解决了,我不知道如何使用喷油器。
@Module({
providers: [{
provide: APP_GUARD,
inject: [Injector],
useFactory: (injector: Injector) => {
return new MultiGuard([AuthGuard, PermissionGuard], injector);
}
}]
})
class AppModule {}
import { CanActivate, ExecutionContext, Type } from '@nestjs/common';
export class MultiGuard implements CanActivate {
constructor(
private readonly guards: Type<CanActivate>[],
private readonly injector: Injector
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const guards = this.guards.map(guard => {
return this.injector.get(guard);
});
const results = await Promise.all(guards);
return results.every(r => !!r);
}
}
最近我做了类似的事情,但没有将警卫类型传递给我的“ multiguard”,而是在工厂中实例化了警卫,而是传递了一组警卫实例。
与NestJS执行防护的方式非常相似。看看guard-consumer.ts
文件。
https://github.com/nestjs/nest/blob/master/packages/core/guards/guards-consumer.ts
@Injectable()
export class GuardsCollection implements CanActivate {
public constructor(private readonly guards: CanActivate[]) {}
public async canActivate(context: ExecutionContext): Promise<boolean> {
for (const guard of this.guards) {
const result = guard.canActivate(context);
if (!(await this.pickResult(result))) {
return false;
}
}
return true;
}
private async pickResult(result: boolean | Promise<boolean> | Observable<boolean>): Promise<boolean> {
if (result instanceof Observable) {
return result.toPromise();
}
return result;
}
}
[在工厂中,我实例化了我的警卫。如果我的守卫有任何依赖关系,我可以在这里通过在Inject
数组中指定依赖关系来解决。
@Module({
providers: [
{
provide: APP_GUARD,
useFactory: (reflector: Reflector) => {
return new GuardsCollection([
new (AuthGuard('jwt'))(),
new RolesGuard(reflector),
]);
},
inject: [Reflector],
},
],
})
export class AuthModule {}