有条件地将服务类实例化为 NestJS 中的提供者

Vin*_*tes 2 javascript dependency-injection nestjs

我有一个名为 的控制器User和两个服务类:UserAdminServiceUserSuperAdminService。当用户向控制器的任何端点发出请求时User,我想检查发出请求的用户是管理员还是超级管理员(基于令牌中的角色)并实例化正确的服务(UserAdminServiceUserSuperAdminService)。请注意,这两个服务实现相同的UserService接口(只是方法的内部发生了一些变化)。我怎样才能用 NestJS 做到这一点?

我尝试过的:

用户模块.ts

providers: [
    {
      provide: "UserService",
      inject: [REQUEST],
      useFactory: (request: Request) => UserServiceFactory(request)
    }
  ],
Run Code Online (Sandbox Code Playgroud)

用户服务.factory.ts

export function UserServiceFactory(request: Request) {

    const { realm_access } = JwtService.parseJwt(
        request.headers["authorization"].split(' ')[1]
    );
    if (realm_access["roles"].includes(RolesEnum.SuperAdmin))
        return UserSuperAdminService;
    else
        return UserAdminService;
}
Run Code Online (Sandbox Code Playgroud)

用户控制器.ts

  constructor(
      @Inject("UserService") private readonly userService: UserServiceInterface
  ) {}
Run Code Online (Sandbox Code Playgroud)

我的代码不起作用的原因之一是因为我返回的是类而不是工厂中的实例化对象,但我希望 NestJS 解决服务依赖关系。有任何想法吗?

Jay*_*iel 6

UserSuperAdminService您可以将和添加UserAdminService到数组中,然后传回 Nest 为inject每个请求创建的实例,而不是传回要实例化的类(Nest 不会处理该类)。

providers: [
    {
      provide: "UserService",
      inject: [REQUEST, UserSuperAdminService, UserAdminService],
      useFactory: (request: Request, superAdminService: UserSuperAdminService, adminService: UserAdminService) => UserServiceFactory(request, superAdminService, adminService)
    }
...
]

export function UserServiceFactory(request: Request, superAdminService: UserSuperAdminService, adminService: UserAdminService) {

    const { realm_access } = JwtService.parseJwt(
        request.headers["authorization"].split(' ')[1]
    );
    if (realm_access["roles"].includes(RolesEnum.SuperAdmin))
        return superAdminService;
    else
        return adminService;
}
Run Code Online (Sandbox Code Playgroud)