nestjs入门 依赖注入
    1、依赖方通过@Injectable()修饰,告诉容器,“我是需要注入的”,同时在构造函数中声明依赖。实例化时,依赖对象将通过构造函数注入。

    1. // order.service.ts
    2. @Injectable()
    3. export class OrderService {
    4. // 注意这里是个简写,等价于在OrderService下面定义了orderDao字段,同时在构造函数中给与赋值
    5. constructor(private readony orderDao: OrderDao) {}
    6. }

    2、定义providor,服务提供者。nest中有三种providor:class、value、factory。class providor就是普通的class,会被实例化后注入给依赖方;value providor可以是任意类型的值,直接注入给依赖方;factory providor是一个工厂方法,容器将先执行该方法,然后将返回值注入给依赖方,factory支持支持异步方法。

    3、配置依赖关系。nest中有module的概念,主要用于描述在该scope下,具体的依赖和输出关系。下面的代码展示了三种providor的配置。

    1. import {OrderDao} from './order.dao';// class providor
    2. //相当于在module里直接使用providers: [ OrderDao ]
    3. const classProvidor = { // 这也是class providor,和👆效果一样
    4. provide: OrderDao,
    5. useClass: OrderDao
    6. }
    7. const valueProvidor = { // value providor
    8. provide: 'Config',
    9. useValue: process.env.NODE_ENV === 'prod' ? {...} : {...}
    10. }
    11. const factoryProvidor = { // factory provoidr
    12. provide: 'Mongo',
    13. useFactory: async () => {
    14. const client await MongoClient.connect(...);
    15. return client.db(dbName);
    16. }
    17. }
    18. @Module({
    19. providers: [OrderDao, valueProvidor, factoryProvidor] // 塞到这里
    20. })
    21. export class OrderModule {}

    4、依赖关系的解析。除了全局module(通过@Global()修饰即可成为全局module),其它module都是一个单独的scope。容器在创建对象时,会在当前scope和全局scope查找依赖。在决定具体使用哪个依赖时,会通过类型匹配或者具名的方式查找。两种使用方式都很简单,代码如下:

    1. class OrderService {
    2. constructor(
    3. readonly orderDao: OrderDao, // class匹配,通过在scope内搜索同类型class的providor
    4. @Inject('Config') config,// 具名匹配,通过在scope内搜索该名字的provoid
    5. ) {}
    6. }

    2,依赖注入实例

    1. //数据库连接 异步&必要实例
    2. export const databaseProviders = [
    3. {
    4. provide: 'DATABASE_CONNECTION',
    5. useFactory: async (): Promise<typeof mongoose> =>
    6. await mongoose.connect('mongodb://localhost/test'),
    7. }
    8. ];
    9. // database.module.ts
    10. import { Module } from '@nestjs/common';
    11. import { databaseProviders } from './database.providers';
    12. @Module({
    13. providers: [...databaseProviders],
    14. exports: [...databaseProviders],
    15. })
    16. export class DatabaseModule {}

    使用useFactory条件

    • 你想提供一个必须使用其他组件(或其他自定义包功能)进行计算的值时。
    • 你想提供异步值(只返回Observable或者Promise),例如数据库连接。

    如果你想使用模块内的组件,必须在inject数组中传递组件。Nest会以相同的顺序传递实例作为factory的参数。

    1. @Module({
    2. controllers: [ UsersController ],
    3. components: [
    4. ChatService,
    5. {
    6. provide: UsersService,
    7. useFactory: (chatService) => {
    8. return Observable.of('customValue');
    9. },
    10. inject: [ ChatService ]
    11. }
    12. ],
    13. })