ใน NestJS document เค้าบอกเราว่า จะทำ IoC ใน NestJS ทำแบบนี้
// user/user.module.ts
@Module({
providers: [UserService],
controllers: [UserController],
})
export class UserModule {}
เพียงเท่านี้ UserController
ก็จะสามารถใช้งาน UserService
ได้เพียงแค่เรา inject UserService
เข้าไปใน constructor
@Controller()
export class UserController {
constructor(
private readonly userService: UserService
) {}
}
นั่นทำให้หลายคนคิดเอาเองว่า ถ้าในกรณีที่ต้องการใช้ service ที่อยู่ใน module อื่น เราก็แค่เอามาใส่ใน Module.providers
น่ะสิ
หน้าตาของ code ใน module ก็เลยกลายเป็นแบบนี้
// user/user.module.ts
@Module({
providers: [UserService, TodoService],
controllers: [UserController],
})
export class UserModule {}
ถ้าเจอ code แบบนี้ ใน code review เราควรจะถามว่า
แล้ว module จะมีความสำคัญอะไร ทำไมถึงยังต้องมี module อยู่ ในเมื่อสามารถเอา service จากไหนก็ได้มาใส่
การเอา service จาก module อื่นมาใช้งานด้วยการใส่ลงไปใน Module.providers
เป็นเรื่องที่ทำได้ เพราะ NestJS ไม่ได้ enforce rules ไว้ แต่มันไม่ได้เหมาะสมเท่าไหร่ เนื่องจากมันทำให้ความสัมพันธ์ระหว่าง module หายไป จนแทบไม่แตกต่างอะไรจากการที่เราเขียนโดยไม่มี module เพราะ module ไปทำ relation ตรงๆกับ service เลย
ท่าที่ถูกต้องคือ
- ถ้าจะใช้ service จาก module อื่น ต้องใช้
Module.imports
import module เข้ามา (ซึ่ง module นั้นจะต้อง export service ออกมาด้วย) - สำหรับ
Module.providers
ใช้สำหรับ internal service เท่านั้น
หน้าตาของ code ที่เหมาะสมก็จะเป็นแบบนี้
// todo/todo.module.ts
@Module({
providers: [TodoService],
exports: [TodoService],
})
export class TodoModule {}
// user/user.module.ts
@Module({
imports: [TodoModule],
providers: [UserService],
controllers: [UserController],
})
export class UserModule {}
Top comments (0)