Circular Dependency trong NestJS

Circular Dependency (phụ thuộc vòng tròn) xảy ra khi Module A imports Module BModule B imports Module A, tạo thành một vòng lặp vô tận. Đây là một vấn đề phổ biến khi xây dựng các ứng dụng phức tạp, và NestJS cung cấp nhiều cách để giải quyết nó.

Khái Niệm Circular Dependency

Circular dependency là khi:
  • Module A → Module B → Module A
  • Service A → Service B → Service A
  • Class A → Class B → Class A

Dấu Hiệu Circular Dependency

Ví Dụ Circular Dependency

1. Service-Level Circular Dependency

2. Module-Level Circular Dependency

Cách Giải Quyết Circular Dependency

1. Forward Reference (forwardRef)

Sử dụng forwardRef() để delay resolution của dependency:
Tạo shared module để break circular dependency:

3. ModuleRef (Dynamic Resolution)

Sử dụng ModuleRef để dynamically resolve dependencies:

4. Lazy Property Injection

Ví Dụ Thực Tế

1. User-Post Relationship

2. Authentication-Authorization Circular Dependency

3. Notification Service Circular Dependency

4. Order-Payment Circular Dependency

Detecting Circular Dependencies

1. Visual Inspection

2. Runtime Detection

Best Practices

1. Prefer Shared Module Pattern

2. Use forwardRef Only When Necessary

3. Architecture Planning

4. Use Interfaces/Abstraction

5. Lazy Loading Dependencies

Complete Example: Breaking Circular Dependency

Troubleshooting

Kết Luận

Circular Dependency là vấn đề phổ biến nhưng có thể tránh được bằng:
  • Shared Module Pattern (Recommended)
  • ForwardRef (Quick fix)
  • ModuleRef (Flexible solution)
  • Lazy Property Injection (For complex scenarios)
  • Architecture Planning (Best prevention)
Best practice là:
  • Thiết kế architecture cẩn thận từ đầu
  • Sử dụng shared modules để break cycles
  • Tránh forwardRef nếu có thể
  • Refactor early khi detect circular dependencies
  • Use dependency graphs để visualize relationships
Điều quan trọng là hiểu rõ why circular dependencies xảy ra, sau đó fix it properly!