Nestjs 按需注入服务

Nestjs 按需注入服务,nestjs,Nestjs,我有一个守卫检查资源的所有权。如果用户是创建该资源的所有者,则他可以访问更新、读取、删除 每个资源都由其自己的服务处理。注释由CommentsModule处理,CommentsModule包含CommentsService等。处理具有所有权的资源的每个服务都实现了一个名为hasOwnery的函数,警卫将调用该函数 如果可能,我希望我的守卫根据调用它的控制器注入正确的服务。因此,如果CommentsController正在调用guard,那么它应该注入并使用CommentsService.hasO

我有一个守卫检查资源的所有权。如果用户是创建该资源的所有者,则他可以访问更新、读取、删除

每个资源都由其自己的服务处理。注释由CommentsModule处理,CommentsModule包含CommentsService等。处理具有所有权的资源的每个服务都实现了一个名为hasOwnery的函数,警卫将调用该函数

如果可能,我希望我的守卫根据调用它的控制器注入正确的服务。因此,如果CommentsController正在调用guard,那么它应该注入并使用CommentsService.hasOwnership

我曾尝试使用动态模块在托管guard的ACModule的导入上注入正确的模块/服务,但这似乎是不可能的,因为我无法正确处理循环依赖关系

由于循环依赖性,将每个服务注入到guard并选择正确的服务对mantain来说是非常麻烦的

有更好的办法吗?这将是理想的行为

@Injectable()
export default class ACGuard implements CanActivate {
  constructor(
    @Inject('SERVICE_KEY') private correctService
  ) {}

  canActivate(context: ExecutionContext) {
    return await correctService.hasOwnership();
  }
}

因为您需要在运行时而不是在编译时使用不同的服务,所以需要采用工厂方法。在添加新资源时进行维护有点麻烦,但这是您必须进行的权衡

我要做的第一件事是创建一个工厂类,根据ExecutionContext确定要使用的正确服务:

export interface IService {
  hasOwnership() : Promise<boolean>;
}

@Injectable()
export class ServiceFactory {

  //Make sure every service returned from this method implements the "IService" interface
  public getCorrectService(context: ExecutionContext) : IService {

    if(context...) {
      return new CommentsService();
    } else if(context...) {
      return new SomeOtherService();
    }
  }
}

这真是一个很好的解释。非常感谢。事实上,我不久前读过这篇文章,权衡了正面和负面,并决定使用特定于服务的警卫。我现在将其标记为正确,这样您就可以得到您的漂亮分数:D@MarceloPerrella很高兴这对你有帮助,很高兴能帮助你:
@Injectable()
export default class ACGuard implements CanActivate {

  constructor(private serviceFactory: ServiceFactory) {}

  canActivate(context: ExecutionContext) {

    //Here's where the magic of this happens...
    const correctService: Iservice = this.serviceFactory.getCorrectService(context);

    return await correctService.hasOwnership();
  }
}