Cả hai đều tách việc tạo dependency ra khỏi việc dùng, nhưng khác nhau ở hướng luồng.
DI — dependency được đưa vào từ ngoài:
class OrderService {
constructor(private repo: OrderRepository, private mailer: Mailer) {}
}Service Locator — class tự đi lấy từ một registry:
class OrderService {
private repo = Locator.get<OrderRepository>('OrderRepository')
}Vì sao DI được ưa hơn:
- Phụ thuộc hiện rõ trong chữ ký. Nhìn constructor là biết class cần gì. Với locator, phải đọc hết thân class mới biết.
- Lỗi phát hiện sớm. Thiếu dependency với DI là lỗi lúc dựng object (thường bắt được lúc biên dịch/khởi động); với locator là lỗi lúc chạy, có khi chỉ nổ ở một nhánh hiếm.
- Test đơn giản. DI chỉ cần truyền bản giả vào constructor. Locator buộc test phải cấu hình registry toàn cục và dọn dẹp sau mỗi test.
- Locator là phụ thuộc thêm. Mọi class giờ phụ thuộc vào chính cái locator, kể cả khi đem sang project khác.
Thực tế: Service Locator vẫn xuất hiện hợp lý trong framework/plugin nơi tập dependency chỉ biết lúc chạy. Với code ứng dụng thường ngày, tiêm qua constructor là mặc định nên chọn.