【问题标题】:How to use literal type as a service constructor parameter in NestJS如何在 NestJS 中使用文字类型作为服务构造函数参数
【发布时间】:2020-07-10 11:40:35
【问题描述】:

我有一个文字类型作为我的服务的构造函数参数:

export type MyType = 'val1' | 'val2';

@Injectable()
export class MyService {
  myType: MyType;
  constructor(private appService: AppService, private myType: MyType = 'val2') {
    this.myType = myType;
  }
}

我在构建时遇到错误

Nest can't resolve dependencies of the MyService (AppService, ?). Please make sure that the argument String at index [1] is available in the AppModule context.

Potential solutions:
- If String is a provider, is it part of the current AppModule?
- If String is exported from a separate @Module, is that module imported within AppModule?
  @Module({
    imports: [ /* the Module containing String */ ]
  })

你会如何解决这个问题?

那是我的 AppModule:

@Module({
  imports: [HttpModule],
  controllers: [AppController],
  providers: [AppService, MyService, HttpClient],
})
export class AppModule {}

【问题讨论】:

  • 你是否在你的模块文件中为 Nest 注入任何东西给MyType
  • @JayMcDoniel 刚刚用我的AppModule更新了这个问题

标签: dependency-injection service nestjs


【解决方案1】:

使用 NestJS,您需要通过 providers 提供构造函数参数。 Nest 通常使用classes 来了解要使用的注入令牌,因为类在 Typescript 和 JavaScript 中都存在。但是,您可以将 @Inject() 装饰器与您自己的注入令牌和自定义值一起使用,以确保 Nest 正确注入该值。这看起来像这样:

@Module({
  providers: [
    MyService,
    {
      provide: 'MyToken', // this can be a symbol or a string
      useValue: 'val2',
    }
    AppService,
  ],
})
export class AppModule {}
export type MyType = 'val1' | 'val2';
@Injectable()
export class MyService {


  constructor(
    private appService: AppService,
    // this token MUST match exactly to the one in the `provide` property of the custom provider
    @Inject('MyToken') private myType: MyType
  ) {}
}

如果要添加其他依赖项,只需确保它们对模块可用。

另一个选项是将myType 标记为@Optional(),这将允许Nest 在无法解析的情况下绕过注入,然后您仍然可以像以前一样轻松地使用默认值

【讨论】:

  • 如你所见,我有默认值private myType: MyType = 'val2',可以在运行时被调用者覆盖。那么如何在运行时使用令牌覆盖该值呢?
  • 你打算如何在运行时调用MyService?你打算让 Nest 处理它还是打算自己制作实例?
  • 如您所见,我在AppModule 中提供MyService,所以我没有手动实例化它
  • 那么您打算如何更改MyType 的值?它会根据什么改变?可以使用useFactory 而不是useValue 来执行此操作,您可以在其中提供一个函数来确定要提供的值,但是如果不知道 如何 您打算决定应该提供什么值。
  • 是的,这是一个很好的问题,我想我可能会坚持使用provide -> value,但是我想知道您将如何处理工厂以及使用提供与工厂有什么区别?
猜你喜欢
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-06
  • 2019-11-11
  • 1970-01-01
  • 2020-06-02
相关资源
最近更新 更多