Dependency Injection


🚀 Tổng quan DI trong Golang

✳️ Dependency Injection là gì?

Là kỹ thuật thiết kế để inject dependencies (phụ thuộc) vào một object thay vì tự tạo ra chúng. Nó giúp:

  • Decouple (giảm phụ thuộc cứng)

  • Dễ unit test (vì có thể mock)

  • Dễ maintainextend


⚙️ 1. Manual DI (cách Go thường dùng)

Golang không có DI framework built-in như Java Spring, nhưng ta có thể dùng Constructor Injection thủ công.

🎯 Ví dụ thực tế

Giả sử bạn có UserService phụ thuộc vào UserRepository:

type UserRepository interface {
    FindByID(id int) (*User, error)
}

type userRepoImpl struct {}

func (r *userRepoImpl) FindByID(id int) (*User, error) {
    return &User{ID: id, Name: "Titan"}, nil
}

🔧 Khởi tạo:

✅ Đây là DI dạng Constructor Injection, đơn giản, rõ ràng và dễ test/mock.


🧪 2. Dễ test nhờ DI


🧱 3. Struct Composition: DI nâng cao

Bạn có thể gom các services lại thành "container" hoặc module:


🧰 4. Dùng Google Wire (DI Compile-time Generator)

Nếu project lớn, manual DI dài dòng, bạn có thể dùng Google Wire:

Khai báo:

Tạo file wire.go:

wire giúp generate code, nhưng vẫn type-safe, compile-time, không runtime magic.


🔁 5. DI runtime: dig (Uber)

Nếu muốn DI container runtime, dùng dig từ Uber:

🧠 dig giống kiểu Spring DI, nhưng nhẹ hơn.


✅ Senior-Level Checklist

Mục tiêu
Status

Manual DI bằng constructor injection

Tách interface để dễ mock

Gom dependencies thành struct container (modular)

Biết dùng Google Wire (compile-time DI)

Biết dùng dig (runtime DI)

Tránh dùng singleton cứng trong service logic


🤝 Tổng kết

  • Manual DI là chuẩn mực trong Go → rõ ràng, testable, không magic

  • Với project lớn, dùng Google Wire để automate wiring

  • Khi cần DI động (plugin, runtime), cân nhắc Uber Dig

  • Đừng lạm dụng singleton → nên inject để dễ test và mock


Last updated