irfo
Moderatör
- Katılım
- 7 Ocak 2026
- Mesajlar
- 183
- Tepkime puanı
- 2
- Puanları
- 18
Go dilinde Dependency Injection (DI), nesne yönelimli dillerdeki kadar karmaşık değildir. Go'nun "interface" yapısı o kadar esnektir ki, çoğu zaman büyük framework'lere ihtiyaç duymadan, sadece doğru yazılım tasarımıyla bağımlılıkları yönetebilirsiniz.
Go dünyasında DI, kodun test edilebilirliğini artırmak ve bileşenler arasındaki sıkı bağı (tight coupling) çözmek için kullanılır.
Go
Go
func GreetUser(db DB) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
user := db.FindUser(1)
fmt.Fprintf(w, "Merhaba %s", user.Name)
}
}
Go dünyasında DI, kodun test edilebilirliğini artırmak ve bileşenler arasındaki sıkı bağı (tight coupling) çözmek için kullanılır.
1. Manuel Bağımlılık Enjeksiyonu (Constructor Injection)
Go'da en yaygın ve önerilen yöntem budur. Birstruct oluştururken ihtiyaç duyduğu bağımlılıkları bir "Constructor" fonksiyonu (New...) aracılığıyla geçmektir.Go
Kod:
type MessageService interface {
Send(msg string) error
}
type EmailService struct{}
func (s EmailService) Send(msg string) error {
fmt.Println("Email gönderiliyor:", msg)
return nil
}
type UserHandler struct {
service MessageService // Bağımlılık burada tanımlı
}
// Constructor: Bağımlılığı dışarıdan alır
func NewUserHandler(s MessageService) *UserHandler {
return &UserHandler{service: s}
}
2. Neden Interface Kullanmalıyız?
DI'nın temel amacı, somut tipler (concrete types) yerine interface'lere güvenmektir. Bu sayede test yazarken gerçek bir veritabanı veya API yerine kolayca "Mock" nesneler kullanabilirsiniz.Go Atasözü: "Accept interfaces, return structs." (Interface kabul et, struct döndür.)
3. Otomatik DI Araçları (Frameworks)
Proje büyüdükçe, onlarca servisi manuel olarak birbirine bağlamak (wiring) sıkıcı ve hata payı yüksek bir işe dönüşebilir. Go ekosisteminde iki ana yaklaşım vardır:A. Google Wire (Compile-time DI)
Google tarafından geliştirilenwire, çalışma zamanında (runtime) yansıma (reflection) kullanmaz. Bunun yerine, bağımlılık ağacını analiz eder ve sizin yerinize normal Go kodu üretir.- Avantajı: Hataları derleme zamanında yakalarsınız. Performans kaybı sıfırdır.
- Dezavantajı: Ekstra bir kod üretme (code generation) adımı gerektirir.
B. Uber FX (Runtime DI)
Uber'in geliştirdiğifx, uygulama ayağa kalkarken bağımlılıkları yansıma (reflection) yoluyla çözer.- Avantajı: Çok esnektir, modüler yapıyı kolaylaştırır.
- Dezavantajı: Hatalar uygulama çalıştıktan sonra ortaya çıkar ve yansıma nedeniyle çok küçük bir performans maliyeti vardır.
4. Bağımlılık Enjeksiyonu Yöntemlerinin Karşılaştırması
| Yöntem | Karmaşıklık | Test Edilebilirlik | Kullanım Alanı |
| Manuel DI | Düşük | Çok Yüksek | Küçük ve Orta Ölçekli Projeler |
| Google Wire | Orta | Çok Yüksek | Büyük, Performans Odaklı Projeler |
| Uber FX | Yüksek | Yüksek | Çok Modüler, Kurumsal Mikroservisler |
5. Pratik Bir İpucu: Fonksiyonel DI
Bazen sadece bir fonksiyonun bağımlılığa ihtiyacı olur. Bu durumda tüm yapıyı değiştirmek yerine yüksek mertebeden fonksiyonlar (higher-order functions) kullanabilirsiniz:Go
func GreetUser(db DB) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
user := db.FindUser(1)
fmt.Fprintf(w, "Merhaba %s", user.Name)
}
}