node.js - NestJs monorepo delad lib-injektion
Jag har en NestJS-applikation med ett par mikrotjänster lagrade i ett enda arkiv (monorepo-approach).
AccessControl-modulen lagras i libs, den bör delas mellan flera mikrotjänster. Den har filen AccessControlModule.ts
@Global()
@Module({
providers: [
{
provide: 'CONNECTION1',
useFactory: (configService: ConfigService) => {
return ClientProxyFactory.create(
configService.getRMQConnection(),
);
},
inject: [ConfigService],
},
ACGuard,
],
exports: [ACGuard],
imports: [ConfigModule],
})
export class AccessControlModule implements OnModuleDestroy {
constructor(
@Inject('CONNECTION1')
protected readonly orgConnection: ClientProxy,
) {}
onModuleDestroy(): any {
this.orgConnection.close();
}
}
Denna fil ansvarar för modulsbeskrivning, den skapar en anslutning till en annan mikrotjänst och tillhandahåller den till ACGuard-tjänsten. ACGuard.ts:
@Injectable()
export class ACGuard implements CanActivate {
constructor(
private readonly reflector: Reflector,
private config: ConfigService,
@Inject('CONNECTION1')
private readonly userConnection: ClientProxy;
) {}
public async canActivate(context: ExecutionContext): Promise<boolean> {
// do some stuff
}
}
Den här delen i sig själv kompilerar bra och fungerar logiskt sett fint. Problemet börjar när jag försöker injicera den i en av mikrotjänsterna. Jag gör det som vanligt genom att lägga till AccessControlModule i import-delen av någon modul. Till exempel KioskModule:
@Module({
imports: [
...
AccessControlModule
],
providers: [
...
KiosksResolver
]
})
export class KiosksModule {}
Eftersom AccessControlModule är markerad som Global och exporterar ACGuard, förväntar jag mig att den kan injiceras i mina providers.
@Resolver('Kiosk')
export class KiosksResolver {
...
@UseGuards(ACGuard)
@Query()
kiosks() {
// ...
}
...
}
Men denna kod misslyckas vid kompileringen med fel:
[Nest] 9964 - 07/05/2020, 21:33:02 [ExceptionHandler] Nest kan inte lösa beroenden för ACGuard (Reflector, ConfigService, ?). Vänligen säkerställ att argumentet CONNECTION1 på index [2] är tillgängligt i KiosksModule-kontexten.
Å andra sidan, om jag injicerar det i KiosksResolver's konstruktor, byggs applikationen framgångsrikt.
Jag kommer att uppskatta all hjälp och alla idéer, tack!
Svar #1
Sättet jag löste detta problem på var genom att exportera CONNECTION1-leverantören i AccessControlModule.ts.
@Module({
providers: [
{
provide: 'CONNECTION1',
useFactory: (configService: ConfigService) => {
return ClientProxyFactory.create(
configService.getRMQConnection(),
);
},
inject: [ConfigService],
},
ACGuard,
],
exports: [ACGuard, 'CONNECTION1'],
imports: [ConfigModule],
})
export class AccessControlModule ...
Med denna export skapar KioskModule sin egen ACGuard men tillhandahåller här anslutningen som exporteras från AccessControlModule. Det är inte klart för mig varför KioskModule inte får den byggda instansen av ACGuard som exporteras från AccessControlModule utan försöker bygga den en gång till.
