NestJs monorepo共享库注入
NestJs monorepo shared lib injection
我有 NestJS 应用程序,其中几个微服务存储在单个存储库中(monorepo 方法)。
AccessControl
模块存储在 libs
中,它应该在多个微服务之间共享。它有 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();
}
}
这个文件负责模块描述,它为另一个微服务创建连接并提供给ACGuard
服务。 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
}
}
这部分本身编译得很好并且逻辑上工作正常。当我尝试将其注入其中一个微服务时,问题就出现了。我像往常一样通过将 AccessControlModule
添加到某些模块的 import
部分来做到这一点。例如 KioskModule
:
@Module({
imports: [
...
AccessControlModule
],
providers: [
...
KiosksResolver
]
})
export class KiosksModule {}
自从 AccessControlModule
标记为 Global
并导出 ACGuard
我希望它可以注入我的供应商。
@Resolver('Kiosk')
export class KiosksResolver {
...
@UseGuards(ACGuard)
@Query()
kiosks() {
// ...
}
...
}
但是这段代码落在编译步骤出错了:
[Nest] 9964 - 05/07/2020, 9:33:02 PM [ExceptionHandler] Nest can't resolve dependencies of the ACGuard (Reflector, ConfigService, ?). Please make sure that the argument CONNECTION1 at index [2] is available in the KiosksModule context.
另一方面,如果我将它注入 KiosksResolver
的构造函数,应用程序将成功构建。
我将不胜感激任何帮助和想法,谢谢!
我解决这个问题的方法是在 AccessControlModule.ts
中导出 CONNECTION1
提供商。
@Module({
providers: [
{
provide: 'CONNECTION1',
useFactory: (configService: ConfigService) => {
return ClientProxyFactory.create(
configService.getRMQConnection(),
);
},
inject: [ConfigService],
},
ACGuard,
],
exports: [ACGuard, 'CONNECTION1'],
imports: [ConfigModule],
})
export class AccessControlModule ...
使用此导出 KioskModule
创建它自己的 ACGuard
但此处提供从 AccessControlModule
导出的连接。
我不清楚为什么 KioskModule
没有从 AccessControlModule
导出 ACGuard
的构建实例,但尝试再次构建它。
我有 NestJS 应用程序,其中几个微服务存储在单个存储库中(monorepo 方法)。
AccessControl
模块存储在 libs
中,它应该在多个微服务之间共享。它有 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();
}
}
这个文件负责模块描述,它为另一个微服务创建连接并提供给ACGuard
服务。 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
}
}
这部分本身编译得很好并且逻辑上工作正常。当我尝试将其注入其中一个微服务时,问题就出现了。我像往常一样通过将 AccessControlModule
添加到某些模块的 import
部分来做到这一点。例如 KioskModule
:
@Module({
imports: [
...
AccessControlModule
],
providers: [
...
KiosksResolver
]
})
export class KiosksModule {}
自从 AccessControlModule
标记为 Global
并导出 ACGuard
我希望它可以注入我的供应商。
@Resolver('Kiosk')
export class KiosksResolver {
...
@UseGuards(ACGuard)
@Query()
kiosks() {
// ...
}
...
}
但是这段代码落在编译步骤出错了:
[Nest] 9964 - 05/07/2020, 9:33:02 PM [ExceptionHandler] Nest can't resolve dependencies of the ACGuard (Reflector, ConfigService, ?). Please make sure that the argument CONNECTION1 at index [2] is available in the KiosksModule context.
另一方面,如果我将它注入 KiosksResolver
的构造函数,应用程序将成功构建。
我将不胜感激任何帮助和想法,谢谢!
我解决这个问题的方法是在 AccessControlModule.ts
中导出 CONNECTION1
提供商。
@Module({
providers: [
{
provide: 'CONNECTION1',
useFactory: (configService: ConfigService) => {
return ClientProxyFactory.create(
configService.getRMQConnection(),
);
},
inject: [ConfigService],
},
ACGuard,
],
exports: [ACGuard, 'CONNECTION1'],
imports: [ConfigModule],
})
export class AccessControlModule ...
使用此导出 KioskModule
创建它自己的 ACGuard
但此处提供从 AccessControlModule
导出的连接。
我不清楚为什么 KioskModule
没有从 AccessControlModule
导出 ACGuard
的构建实例,但尝试再次构建它。