Giới thiệu về Injection Scope trong NestJS
Trong loạt bài viết về NestJS, một khái niệm quan trọng mà bạn không thể bỏ qua là Injection Scope. Vậy Injection Scope là gì và tại sao nó lại quan trọng trong quá trình phát triển ứng dụng NestJS? Hãy cùng tìm hiểu qua bài viết dưới đây để nắm rõ hơn về khái niệm này và các loại scope trong NestJS.
Injection Scope Là Gì?
Injection Scope trong NestJS là cách mà framework này quản lý vòng đời (lifecycle) của các provider trong ứng dụng. Khi một provider được sử dụng, vòng đời của nó sẽ ảnh hưởng đến cách NestJS tạo ra và quản lý instance của provider đó.
Các Loại Injection Scope Trong NestJS
NestJS hỗ trợ ba loại injection scopes chính, mỗi loại sẽ phù hợp với những tình huống sử dụng khác nhau.
1. Scope Mặc Định (Singleton Scope)
Mô Tả:
- Đây là scope mặc định của NestJS.
- Một instance duy nhất của provider sẽ được tạo và chia sẻ trong toàn bộ ứng dụng.
Ứng Dụng Thực Tế:
- Thường dành cho các service như
DatabaseService
, trong đó một kết nối duy nhất được duy trì trong suốt vòng đời của ứng dụng.
Ví Dụ:
typescript
@Injectable()
export class DatabaseService {
private connection: any;
constructor() {
this.connection = this.createConnection();
}
private createConnection() {
return "Database connection"; // Logic tạo kết nối database
}
getConnection() {
return this.connection;
}
}
typescript
@Controller('users')
export class UserController {
constructor(private readonly databaseService: DatabaseService) {}
@Get()
getUsers() {
return this.databaseService.getConnection(); // Cùng một instance
}
}
2. Scope Yêu Cầu (Request Scope)
Mô Tả:
- Mỗi yêu cầu HTTP mới sẽ tạo ra một instance mới của provider.
- Phù hợp cho các tình huống mà dữ liệu hoặc trạng thái cần được gắn với từng yêu cầu cụ thể.
Ứng Dụng Thực Tế:
- Các dịch vụ quản lý dữ liệu của người dùng trong một request, chẳng hạn như
AuthService
lưu trạng thái phiên làm việc.
Ví Dụ:
typescript
@Injectable({ scope: Scope.REQUEST })
export class LoggerService {
constructor(@Inject(REQUEST) private readonly request: Request) {}
log() {
console.log(`Request ID: ${this.request.id}`);
}
}
typescript
@Controller('logs')
export class LogController {
constructor(private readonly loggerService: LoggerService) {}
@Get()
logRequest() {
this.loggerService.log(); // Instance mới cho mỗi request
}
}
3. Scope Tạm Thời (Transient Scope)
Mô Tả:
- Một instance mới của provider sẽ được tạo mỗi lần provider được inject.
- Thích hợp cho các dịch vụ có trạng thái ngắn hạn hoặc tạm thời.
Ứng Dụng Thực Tế:
- Các dịch vụ đơn giản mà không cần thiết phải sử dụng lại như
RandomGeneratorService
tạo ra các giá trị ngẫu nhiên.
Ví Dụ:
typescript
@Injectable({ scope: Scope.TRANSIENT })
export class RandomGeneratorService {
generate() {
return Math.random();
}
}
typescript
@Controller('random')
export class RandomController {
constructor(private readonly randomGeneratorService: RandomGeneratorService) {}
@Get()
getRandom() {
return this.randomGeneratorService.generate(); // Instance mới mỗi lần gọi
}
}
Các Khái Niệm Liên Quan
-
Dependency Injection (DI):
- Injection scopes là một phần quan trọng trong DI, giúp NestJS quản lý cách thức khởi tạo và chia sẻ các dependency.
-
Module:
- Các providers thường được sự khai báo trong module, và scope của chúng sẽ ảnh hưởng đến cách các module khác sử dụng chúng.
-
Lifecycle Hooks:
- Scope ảnh hưởng đến lifecycle hooks như
OnModuleInit
,OnApplicationBootstrap
, và nhiều hook khác.
- Scope ảnh hưởng đến lifecycle hooks như
-
Performance:
Singleton
tiết kiệm nhiều tài nguyên hơn vì chỉ khởi tạo một lần.Request
vàTransient
có thể tốn kém hơn do tạo ra nhiều instance.
So Sánh Các Scope
Scope | Instance Được Tạo Khi Nào? | Dùng Chung Cho Toàn Ứng Dụng? |
---|---|---|
Singleton | Khi ứng dụng khởi chạy | Có |
Request | Khi có một HTTP request mới | Không |
Transient | Mỗi lần provider được inject | Không |
Khi Nào Sử Dụng Từng Loại Scope?
-
Singleton:
- Dành cho các dịch vụ không cần trạng thái (
stateless services
). - Các dịch vụ như kết nối cơ sở dữ liệu.
- Dành cho các dịch vụ không cần trạng thái (
-
Request:
- Dùng cho các dịch vụ cần trạng thái riêng biệt cho mỗi request.
- Như các dịch vụ liên quan đến người dùng.
-
Transient:
- Phù hợp cho các dịch vụ chỉ tồn tại trong thời gian ngắn.
- Các dịch vụ xử lý logic không cần lưu trữ trạng thái.
Tài Nguyên Tham Khảo
- Hướng Dẫn NestJS về Injection Scopes
- Repository GitHub của tôi về cách thực hiện
- Bài viết gốc của tôi
Hy vọng bài viết này giúp bạn hiểu rõ hơn về Injection Scope trong NestJS, giúp nâng cao khả năng phát triển ứng dụng của bạn.
source: viblo