在Nestjs中,向模块提供抽象类无法正常工作

问题描述 投票:0回答:1
const userRepositoryProvider = {
  provide: UserRepository, // abstract class
  useClass: ConcreteUserRepository, // concrete class
};

在模块 A 中,我提供并导出一个如上所示的提供程序。 (全部设置为可注射)

在另一个模块 B 中,我正在导入模块 A。在模块 B 的服务中,我正在注入从模块 A 导入的提供程序,例如:

private readonly userRepo: UserRepository

当我构建并执行应用程序时,Nest 不会解析依赖关系,并告诉 UserRepository 是“?”。


奇怪的是,当我将提供者提供令牌设置为字符串时,如下所示:

const userRepositoryProvider = {
  provide: "UserRepository", // abstract class
  useClass: ConcreteUserRepository, // concrete class
};

并注入提供者,如下所示:

@Inject("UserRepository") private readonly userRepo: UserRepository

它完美地按照我的预期工作,没有任何异常。

那么为什么会有这样的表现呢?这可能是一个错误吗?


最后,我提供了这两个抽象类和具体类。但我认为这并不重要,因为字符串提供令牌可以正常工作,而抽象类提供令牌则不能正常工作。

@Injectable()
export abstract class UserRepository {
  getUser(id: bigint): User {
    return User.create(id);
  }
}

@Injectable()
export class ConcreteUserRepository extends UserRepository {}
const userRepositoryProvider = {
  provide: UserRepository, // abstract class
  useClass: ConcreteUserRepository, // concrete class
};

在模块 A 中,我提供并导出一个如上所示的提供程序。 (全部设置为可注射)

在另一个模块 B 中,我正在导入模块 A。在模块 B 的服务中,我正在注入从模块 A 导入的提供程序,例如:

private readonly userRepo: UserRepository

当我构建并执行应用程序时,Nest 不会解析依赖关系,并告诉 UserRepository 是“?”。


奇怪的是,当我将提供者提供令牌设置为字符串时,如下所示:

const userRepositoryProvider = {
  provide: "UserRepository", // abstract class
  useClass: ConcreteUserRepository, // concrete class
};

并注入提供者,如下所示:

@Inject("UserRepository") private readonly userRepo: UserRepository

它完美地按照我的预期工作,没有任何异常。

那么为什么会有这样的表现呢?这可能是一个错误吗?


最后,我提供了这两个抽象类和具体类。但我认为这并不重要,因为字符串提供令牌可以正常工作,而抽象类提供令牌则不能正常工作。

@Injectable()
export abstract class UserRepository {
  getUser(id: bigint): User {
    return User.create(id);
  }
}

@Injectable()
export class ConcreteUserRepository extends UserRepository {}

  • 正常工作案例

  • 不正常工作案例

  • 错误日志

typescript class dependency-injection nestjs nest
1个回答
0
投票

在 NestJS 中,您定义提供程序 - 对于注入令牌,您必须使用字符串文字(正如您在问题中提到的),或者更好的是,您可以定义一个符号以使注入机制起作用:

export const UserRepositoryToken = Symbol('UserRepository');

现在您可以创建一个提供者,并在所需模块的提供者数组中注册:

const userRepositoryProvider: Provider = {
  provide: UserRepositoryToken, // injection token
  useClass: ConcreteUserRepository, // concrete class
};

最后将其注入到服务构造函数中:

@Inject(UserRepositoryToken) private readonly userRepo: UserRepository
© www.soinside.com 2019 - 2024. All rights reserved.