Providers trong NestJS

Provider là một khái niệm cơ bản trong NestJS. Hầu hết các classes trong NestJS đều có thể được coi là provider - services, repositories, factories, helpers, v.v. Ý tưởng chính của provider là nó có thể inject dependencies vào các classes khác.

Khái niệm Provider

Provider là một class được NestJS quản lý thông qua Dependency Injection Container. Khi bạn khai báo một provider trong module, NestJS sẽ:
  1. Tạo instance của class đó
  2. Quản lý vòng đời của instance
  3. Inject vào các classes khác khi cần
Decorator @Injectable() đánh dấu class này là một provider.

Cách Khai Báo Providers

1. Value Provider (useValue)

Cung cấp một giá trị tĩnh:
Khi nào sử dụng:
  • Testing với mock data
  • Cung cấp configuration constants
  • Các giá trị tĩnh không cần initialization

2. Class Provider (useClass)

Cung cấp một class khác thay vì class gốc:
Khi nào sử dụng:
  • Strategy pattern - swap implementations
  • Environment-based providers (dev/prod)
  • Testing với mock classes

3. Factory Provider (useFactory)

Tạo instance thông qua một factory function:
Với dependencies:
Khi nào sử dụng:
  • Initialization phức tạp
  • Tạo instance dựa trên configuration
  • Dependencies động

4. Alias Provider (useExisting)

Tạo alias cho một provider khác:
Khi nào sử dụng:
  • Cung cấp nhiều names cho cùng một service
  • Backward compatibility

Scopes (Phạm vi) của Providers

1. Singleton (DEFAULT)

Một instance duy nhất cho toàn bộ ứng dụng:
Đặc điểm:
  • Instance được tạo một lần
  • Chia sẻ giữa toàn bộ ứng dụng
  • Tốt hơn về performance
  • Dùng cho stateless services

2. Request

Một instance mới cho mỗi request:
Đặc điểm:
  • Instance mới cho mỗi HTTP request
  • Có thể lưu trữ dữ liệu request-specific
  • Tốn tài nguyên hơn singleton
  • Dùng cho services cần isolation giữa requests

3. Transient

Một instance mới được tạo mỗi khi được inject:
Đặc điểm:
  • Instance mới mỗi lần inject
  • Nhiều instances trong một request
  • Tốn tài nguyên nhất
  • Dùng hiếm khi
So sánh scopes:

Dependency Injection (DI)

Constructor Injection

Cách phổ biến nhất - inject qua constructor:

Property Injection

Inject trực tiếp vào property (ít dùng):

Method Injection

Inject vào method parameters (cực hiếm):

Ví dụ Thực Tế

Service với Multiple Dependencies

Factory Provider với Configuration

Custom Provider Token

Conditional Providers

Optional Dependencies

Đánh dấu dependency là optional:

Best Practices

1. Một Responsibility (Single Responsibility)

Mỗi provider chỉ nên có một mục đích duy nhất:

2. Inject Interfaces, không Classes

Giúp testing và flexibility:

3. Sử dụng Appropriate Scopes

Chọn scope phù hợp:

4. Tránh Circular Dependencies

Sử dụng lazy loading hoặc shared modules:

Testing Providers

Mock providers để test dễ dàng:

Kết Luận

Providers là nền tảng của Dependency Injection trong NestJS. Hiểu rõ về providers giúp bạn:
  • Tổ chức code logic và dễ bảo trì
  • Viết unit tests dễ dàng hơn
  • Quản lý dependencies một cách rõ ràng
  • Xây dựng ứng dụng linh hoạt và mở rộng
  • Áp dụng các design patterns như Factory, Strategy, Singleton
Sử dụng providers đúng cách là chìa khóa để xây dựng các ứng dụng NestJS chất lượng cao.