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 providor
provide: 'Config',
useValue: process.env.NODE_ENV === 'prod' ? {...} : {...}
}
const factoryProvidor = { // factory provoidr
provide: '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.ts
import { 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 ]
}
],
})