Skip to content

多种 Provider 的多种引入方式

通过类来引入

rovider 一般都是用@Injectable 装饰的类

ts
@Injectable()
export class AppService {
  getWater(): string {
    return "hello water";
  }
}

在模块的 providers 中,通过类来引入,比如服务这种提供者。

ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";

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

其实上面的提供者是一种简写方式,完整的写法如下:

ts
@Module({
  imports:[],
  controllers: [AppController],
  providers: [{
    provide: AppService,
    useClass: AppService,
  }],
})

通过 token 引入

通过 provide 指定注入的 token,通过 useClass 指定注入的对象的类,Nest 会自动对它做实例化再注入

ts
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getWater(): string {
    return this.appService.getWater();
  }
}

这里是使用的构造函数注入,也可以通过属性注入。

ts
@Controller()
export class AppController {
  @Inject()
  private readonly appService: AppService;

  @Get()
  getWater(): string {
    return this.appService.getWater();
  }
}

通过@Inject 装饰器来注入。指定注入的 provider 的 token 就行了,而且这个 token 还可以是一个字符串。

ts
@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: "app_service",
      useClass: AppService,
    },
  ],
})
export class AppModule {}

那么当 token 是字符串的时候,那么导入的方式就变成下面这样了。

ts
@Controller()
export class AppController {
  constructor(@Inject("app_service") private readonly appService: AppService) {}
  // 或者
  // @Inject('app_service')
  // private readonly appService: AppService;

  @Get()
  getWater(): string {
    return this.appService.getWater();
  }
}

指定一个值

除了指定一个类,还可以指定一个值,比如字符串,数字,布尔值等。

ts
@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: "water_token",
      useValue: {
        name: "water",
        age: 18,
      },
    },
  ],
})
export class AppModule {}
ts
@Controller()
export class AppController {
  constructor(
    @Inject("water_token")
    private readonly waterToken: { name: string; age: number }
  ) {}
}

也可以通过 useFactory 来动态生成一个值。

ts
@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: "water_token",
      useFactory: () => {
        return {
          name: "water",
          age: 18,
        };
      },
    },
  ],
})
export class AppModule {}

使用方式与上面一致。同时使用 useFactory 还支持参数传递。

ts
{
    provide: 'water_token',
    useFactory: (name: string) => {
      return {
        name: name,
        age: 18,
      }
    },
    inject: ['name']
}

provide 还可以通过 useExisting 来指定别名,比如把 name 这个 provider 的别名指定为 water_token。

ts
@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: "water_token",
      useExisting: "name",
    },
  ],
})
export class AppModule {}

总结

通过类来引入,通过 token 来引入,通过 useValue 来引入一个值,通过 useFactory 来引入一个值,通过 useExisting 来引入别名。

以上就是 Nest 中 Provider 的多种引入方式。