在NestJS中通常一個(gè)模塊有如下結(jié)構(gòu)
- person.module.ts - 定義模塊類
- person.service.ts - 定義服務(wù)類
- person.controller.ts - 定義控制器類
- person.module.ts - 模塊類
這里模塊類 person.module.ts 大致有如下內(nèi)容
import { Module } from '@nestjs/common';
import { PersonController } from './person.controller';
import { PersonService } from './person.service'
@Module({
imports: [],
controllers: [PersonController],
providers: [PersonService],
})
export class PersonModule {}
但是如果此時(shí)我們的service類有多個(gè)實(shí)現(xiàn),具體使用哪個(gè)實(shí)現(xiàn)類需要根據(jù)環(huán)境來決定時(shí)谍夭,應(yīng)該怎么處理呢黑滴?
此時(shí)我們就可以使用NestJS中provider的useClass來實(shí)現(xiàn)了,看下面例子:
person.module.ts
export interface Person {
id: number;
name: string;
email: string;
}
person.service.ts
import { Injectable } from '@nestjs/common';
import { Person } from './person';
export abstract class PersonService {
abstract findAll(): Promise<Person[]> ;
abstract findOne(id: number): Promise<Person> ;
}
export class RealPersonService extends PersonService {
persons: Person[] = [];
constructor() {
super();
this.persons = [
{ id: 1, name: 'John.real', email: 'john@example.com' },
{ id: 2, name: 'Jane.real', email: 'jane@example.com' },
{ id: 3, name: 'Bob.real', email: 'bob@example.com' },
];
}
async findAll(): Promise<Person[]> {
return this.persons;
}
async findOne(id: number): Promise<Person> {
const persons = this.persons.filter((person) => person.id == id);
return persons[0];
}
}
export class MockPersonService extends PersonService {
persons: Person[] = [];
constructor() {
super();
this.persons = [
{ id: 1, name: 'John.mock', email: 'john@example.com' },
{ id: 2, name: 'Jane.mock', email: 'jane@example.com' },
{ id: 3, name: 'Bob.mock', email: 'bob@example.com' },
];
}
async findAll(): Promise<Person[]> {
return this.persons;
}
async findOne(id: number): Promise<Person> {
const persons = this.persons.filter((person) => person.id == id);
return persons[0];
}
}
- 這里抽象類PersonService定義了要提供的方法(這里之所以沒有使用Interface是為了在module里配置的時(shí)候可以寫類名紧索,如果是Interface的話provider是不能寫類的;
- 另外提供了兩個(gè)實(shí)例類菜谣,一個(gè)real實(shí)現(xiàn)珠漂,一個(gè)mock實(shí)現(xiàn),為了簡單只是修改其中person.name的值尾膊;
person.controller.ts
import {
Controller,
Get,
Param,
} from '@nestjs/common';
import { Person } from './person';
import { PersonService } from './person.service';
@Controller('persons')
export class PersonController {
constructor(private readonly personService: PersonService) {}
@Get()
async findAll(): Promise<Person[]> {
return this.personService.findAll();
}
@Get(':id')
async findOne(@Param('id') id: number): Promise<Person> {
return this.personService.findOne(id);
}
}
- 控制類簡單注入了PersonService類媳危;
person.module.ts
import { Module } from '@nestjs/common';
import { PersonController } from './person.controller';
import { PersonService, RealPersonService, MockPersonService } from './person.service'
const PersonServiceProvider = {
provide: PersonService,
useClass: process.env.NODE_ENV === 'development'
? MockPersonService
: RealPersonService,
}
@Module({
imports: [],
controllers: [PersonController],
providers: [PersonServiceProvider],
})
export class PersonModule {}
- module類定義了一個(gè)PersonServiceProvider,其中使用useClass來根據(jù)環(huán)境變量來決定使用具體那個(gè)PersonService的實(shí)現(xiàn)類冈敛;
測試
npm run start:dev
或者
export NODE_ENV=development && npm run start:dev