Trong Laravel (kể cả Laravel 12), bind()singleton() đều dùng để đăng ký service vào Service Container, nhưng khác nhau ở vòng đời instance.


🔹 1. bind() – tạo instance mới mỗi lần resolve

$this->app->bind(UserService::class, function ($app) {
    return new UserService();
});

👉 Mỗi lần bạn gọi:

app(UserService::class);

➡️ Laravel sẽ tạo object mới hoàn toàn

✅ Khi nào dùng bind()

  • Class stateless (không giữ state nội bộ)
  • Service nhẹ, không tốn tài nguyên
  • Muốn mỗi lần dùng là fresh instance
  • Ví dụ:
    • Repository
    • Helper service
    • Transformer / Formatter

🔹 2. singleton() – dùng 1 instance duy nhất

$this->app->singleton(CacheService::class, function ($app) {
    return new CacheService();
});

👉 Dù gọi bao nhiêu lần:

app(CacheService::class);

➡️ Luôn trả về cùng 1 object


✅ Khi nào dùng singleton()

  • Service nặng / tốn tài nguyên
  • Cần giữ state
  • Muốn share dữ liệu xuyên suốt request
  • Ví dụ:
    • Cache handler (Redis, memory cache)
    • Config loader
    • Connection (API client, DB wrapper custom)
    • Logger

🔥 So sánh nhanh

Tiêu chíbind()singleton()
InstanceMỗi lần mới1 instance duy nhất
MemoryTốn hơnTiết kiệm hơn
StateKhông giữCó thể giữ
Use caseStateless serviceShared service

⚠️ Lưu ý quan trọng (rất hay dính bug)

❌ Sai lầm phổ biến

Dùng singleton() cho service có state động:

class CartService {
    public $items = [];
}

➡️ Nếu dùng singleton → user A add item, user B cũng thấy 😅
(vì share cùng instance trong lifecycle)


🧠 Góc nhìn nâng cao (quan trọng với system lớn)

Với hệ thống lớn như bạn đang làm (multi-domain, queue, cache...):

  • singleton() phù hợp:
    • Redis client (reuse connection)
    • Elasticsearch client
    • Config registry
  • bind() phù hợp:
    • Business logic service (UserService, PostService)
    • Data processing pipeline

🔥 Tip tối ưu performance

Laravel resolve dependency rất nhiều → nếu object nặng:

👉 Dùng singleton() + lazy load bên trong
(đỡ tạo nhiều object không cần thiết)


✅ Kết luận ngắn gọn

  • Không có state + nhẹ → bind()
  • Có state / nặng / cần reuse → singleton()