nestjs入门 依赖注入
1、依赖方通过@Injectable()修饰,告诉容器,“我是需要注入的”,同时在构造函数中声明依赖。实例化时,依赖对象将通过构造函数注入。
// order.service.ts@Injectable()export class OrderService {// 注意这里是个简写,等价于在OrderService下面定义了orderDao字段,同时在构造函数中给与赋值constructor(private readony orderDao: OrderDao) {}}
2、定义providor,服务提供者。nest中有三种providor:class、value、factory。class providor就是普通的class,会被实例化后注入给依赖方;value providor可以是任意类型的值,直接注入给依赖方;factory providor是一个工厂方法,容器将先执行该方法,然后将返回值注入给依赖方,factory支持支持异步方法。
3、配置依赖关系。nest中有module的概念,主要用于描述在该scope下,具体的依赖和输出关系。下面的代码展示了三种providor的配置。
import {OrderDao} from './order.dao';// class providor//相当于在module里直接使用providers: [ OrderDao ]const classProvidor = { // 这也是class providor,和👆效果一样provide: OrderDao,useClass: OrderDao}const valueProvidor = { // value providorprovide: 'Config',useValue: process.env.NODE_ENV === 'prod' ? {...} : {...}}const factoryProvidor = { // factory provoidrprovide: 'Mongo',useFactory: async () => {const client await MongoClient.connect(...);return client.db(dbName);}}@Module({providers: [OrderDao, valueProvidor, factoryProvidor] // 塞到这里})export class OrderModule {}
4、依赖关系的解析。除了全局module(通过@Global()修饰即可成为全局module),其它module都是一个单独的scope。容器在创建对象时,会在当前scope和全局scope查找依赖。在决定具体使用哪个依赖时,会通过类型匹配或者具名的方式查找。两种使用方式都很简单,代码如下:
class OrderService {constructor(readonly orderDao: OrderDao, // class匹配,通过在scope内搜索同类型class的providor@Inject('Config') config,// 具名匹配,通过在scope内搜索该名字的provoid) {}}
2,依赖注入实例
//数据库连接 异步&必要实例export const databaseProviders = [{provide: 'DATABASE_CONNECTION',useFactory: async (): Promise<typeof mongoose> =>await mongoose.connect('mongodb://localhost/test'),}];// database.module.tsimport { Module } from '@nestjs/common';import { databaseProviders } from './database.providers';@Module({providers: [...databaseProviders],exports: [...databaseProviders],})export class DatabaseModule {}
使用useFactory条件
- 你想提供一个必须使用其他组件(或其他自定义包功能)进行计算的值时。
- 你想提供异步值(只返回Observable或者Promise),例如数据库连接。
如果你想使用模块内的组件,必须在inject数组中传递组件。Nest会以相同的顺序传递实例作为factory的参数。
@Module({controllers: [ UsersController ],components: [ChatService,{provide: UsersService,useFactory: (chatService) => {return Observable.of('customValue');},inject: [ ChatService ]}],})
