Bağımlılık Enjeksiyonu: Sınıflar Gereksinimlerini Nasıl Alır?
Bağımlılık enjeksiyonunun ne olduğunu, IoC ile ilişkisini, enjeksiyon türlerini ve test edilebilirliğe katkısını örnekle öğrenin.
Bağımlılık enjeksiyonu nedir?
Bir sınıf çalışmak için başka nesnelere ihtiyaç duyar: veritabanı bağlantısı, e-posta gönderici, ödeme servisi. Bunlara bağımlılık denir. Sınıf bu nesneleri kendi içinde oluşturursa (örneğin doğrudan yeni bir nesne yaratırsa), o somut sınıfa sıkı sıkıya bağlanır. Bağımlılık enjeksiyonu, nesnelerin dışarıdan verilmesidir.
Sınıf neye ihtiyacı olduğunu bildirir, kimin sağlayacağı ise sınıfın sorunu değildir. Bu küçük değişiklik, kodun esnekliğini ve test edilebilirliğini belirgin biçimde artırır.
Nasıl çalışır?
Önce arayüz (sözleşme) tanımlanır: örneğin bildirim gönderen bir arayüz. Sınıf bu arayüze bağımlıdır; arkasındaki gerçek uygulamayı bilmez. Çalışma anında gerçek uygulama sınıfa verilir. Enjeksiyonun başlıca biçimleri:
- Kurucu (constructor) enjeksiyonu: Bağımlılıklar nesne oluşturulurken verilir. En yaygın ve en güvenli biçimdir, çünkü nesne eksiksiz hazır doğar.
- Özellik (setter) enjeksiyonu: Bağımlılık, nesne oluşturulduktan sonra bir alan aracılığıyla atanır. İsteğe bağlı bağımlılıklar için uygundur.
- Metot enjeksiyonu: Bağımlılık yalnızca belirli bir metoda parametre olarak verilir.
Çoğu durumda kurucu enjeksiyonu tercih edilir, çünkü bir sınıfın neye ihtiyaç duyduğu kurucusuna bakılarak açıkça görülür.
Küçük bir örnek
Örneğin bir sipariş servisi, sipariş alındığında müşteriye e-posta göndersin. Servis, e-posta gönderen sınıfı kendi içinde oluşturursa, test sırasında gerçekten e-posta gitmesini engellemek zorlaşır. Bağımlılık enjeksiyonuyla servis, bir bildirim arayüzü ister. Üretimde gerçek e-posta gönderici, testte ise e-posta göndermeyen sahte bir uygulama verilir.
Kod değişmeden davranış değişir. Yarın bildirim kanalı mesajlaşma uygulamasına çevrilirse, sipariş servisine dokunmadan yeni uygulama bağlanır.
IoC ve DI konteyneri
Kontrolün tersine çevrilmesi (Inversion of Control, IoC), bir tasarım ilkesidir: nesneleri oluşturma ve birbirine bağlama kontrolü sınıfın elinden alınıp dışarıya bırakılır. Bağımlılık enjeksiyonu bu ilkenin en yaygın uygulamasıdır.
Büyük uygulamalarda nesneleri elle bağlamak zorlaşır. Bu yüzden birçok çerçeve bir DI konteyneri sunar. Konteyner hangi arayüz için hangi uygulamanın kullanılacağını yapılandırmadan okur, nesneleri oluşturur ve gerekli yerlere verir. Ayrıca nesnenin yaşam döngüsünü yönetir: her istek için yeni bir örnek mi, uygulama boyunca tek bir örnek mi kullanılacağı konteyner yapılandırmasında belirlenir.
Faydaları ve anti-desenler
Faydaları:
- Test edilebilirlik: Gerçek bağımlılıklar sahte uygulamalarla değiştirilebilir.
- Esneklik: Uygulamalar kodu değiştirmeden değiştirilebilir.
- Daha net sorumluluklar: Sınıfın bağımlılıkları kurucusunda görünür.
- Daha kolay bakım: Değişiklik etkisi bağlanmış noktalarla sınırlı kalır.
Sık görülen anti-desenler de bilinmelidir. Servis bulucu (service locator) kullanımı bağımlılıkları gizler. Kurucuda çok fazla bağımlılık, sınıfın fazla iş yaptığının işaretidir. Konteynere her yerden doğrudan erişmek, DI'ın amacını bozar. Her sınıf için gereksiz arayüz yaratmak ise kodu şişirir.
Nerede kullanılır ve nasıl öğrenilir?
Bağımlılık enjeksiyonu, kurumsal uygulama çerçevelerinin ve modern web çerçevelerinin çoğunda temel bir yapı taşıdır. Katmanlı mimaride iş mantığını veri erişiminden ayırmak, birim testi yazmak ve modüler tasarım yapmak için kullanılır.
Mindset kataloğundaki Yazılımda Bağımlılık Enjeksiyonu ve IoC programının modül başlıkları IoC ilkesi ve enjeksiyon kalıpları, konteyner yapılandırması ve yaşam döngüsü ile test edilebilirlik ve anti-desenler konularını içerir.
İlgili Mindset programı
Yazılımda Bağımlılık Enjeksiyonu ve IoC
Sık sorulan sorular
Bağımlılık enjeksiyonu ile IoC aynı şey midir?
Birbirine çok yakındır ama aynı değildir. IoC, nesne oluşturma ve bağlama kontrolünün dışarıya bırakılmasını anlatan genel bir ilkedir. Bağımlılık enjeksiyonu ise bu ilkeyi uygulamanın en yaygın tekniğidir. IoC'ye ulaşmanın başka yolları da vardır, örneğin olay tabanlı yaklaşımlar.
Küçük projelerde DI konteyneri gerekli mi?
Her zaman değil. Küçük uygulamalarda bağımlılıkları kurucu aracılığıyla elle vermek yeterli ve daha okunur olabilir. Konteyner, bağımlılık grafı büyüdüğünde ve yaşam döngüsü yönetimi gerektiğinde değer katar. Önce prensibi uygulamak, aracı sonra eklemek mantıklıdır.
Kurucu enjeksiyonu neden tercih edilir?
Çünkü nesne oluşturulduğu anda gerekli tüm bağımlılıklarıyla hazırdır ve eksik bağımlılıkla çalışması mümkün değildir. Bağımlılıklar sonradan değişemeyeceği için nesnenin durumu da öngörülebilir kalır. Ayrıca sınıfın neye ihtiyaç duyduğu kurucudan okunabilir. Bu da kodu anlamayı ve test yazmayı kolaylaştırır.
Bağımlılık enjeksiyonu performansı etkiler mi?
Günlük uygulamalarda etkisi ihmal edilebilir düzeydedir. Konteyner nesneleri başlangıçta ya da ihtiyaç anında oluşturur; maliyet çoğu zaman gözle görülmez. Performans kritikse yaşam döngüsü seçimi ve gereksiz nesne üretimi gözden geçirilmeli, ama bu, DI'dan vazgeçme nedeni sayılmaz.