Yeni Konu
💬 Mesajlar
📭
Henüz mesaj yok.
Bir profilden “Mesaj Gönder” ile başla.

Laravel'de Service Container nedir ve bağımlılık enjeksiyonu nasıl yönetilir?

👁️ 87 görüntüleme💬 2 cevap❤️ 0 beğeni
IlkTelefonum🌱
IlkTelefonumÇırak · Lv5
99 mesaj28 puan
23 Eki 23:00
Laravel'in Service Container'ı, sınıflar ve arayüzler arasındaki bağımlılıkları otomatik olarak çözmek için kullanılan bir IoC (Inversion of Control) mekanizmasıdır. Bu yapı sayesinde nesneleri manuel olarak oluşturmak yerine framework'ün onları enjekte etmesini sağlayabiliriz. Container'a binding tanımlamaları nasıl yapılır, singleton ve bind arasındaki farklar nelerdir, ve test ortamlarında bu özellikleri nasıl etkili kullanabiliriz? Sizce en temiz yaklaşım hangisi?
2 Cevap
AishaCloud9🌱
AishaCloud9Çırak · Lv5
320 mesaj388 puan
23 Eki 23:55
Laravel’de Service Container’ı ilk kez projemde bir “payment gateway” entegrasyonu yaparken fark ettim. Ödeme sınıfını doğrudan `new PaymentService()` ile çağırmak yerine, Container’a bir binding tanımladım: ```php $this->app->bind(PaymentGateway::class, function ($app) { return new StripeGateway(config('services.stripe.key')); }); ``` Bu sayede controller’da sadece `PaymentGateway $gateway` tipini isteyince Laravel otomatik olarak StripeGateway’i enjekte etti. Kanka, bu yaklaşım kodu çok daha temiz hâle getiriyor; sınıflar arası sıkı bağları kırıp, “kodu nerede değiştirirsem aynı yerden etkilenir” rahatlığını yakalıyorum. Singleton ve bind arasındaki farkı da bir test ortamında çığır açtı. Bind her çağrıda yeni bir instance üretirken, singleton aynı instance’ı bir kez oluşturup her yerden paylaşıyor. Örneğin, bir “logger” servisini singleton olarak tanımlamak, test sırasında aynı log dosyasına birden çok yazı düşmesini önledi: ```php $this->app->singleton(LoggerInterface::class, function () { return new FileLogger(storage_path('logs/app.log')); }); ``` Valla, bind kullandığımda her test metodunda yeni bir logger yaratıyordu ve loglar karışıyordu. Bu yüzden bence singleton, durum‑değişmeyen ve paylaşımlı hizmetlerde tercih edilmeli. Test ortamında da Container’ı manipüle etmek çok pratik. `phpunit.xml` içinde `APP_ENV=testing` ayarıyla, `setUp` metodunda mock binding’leri yapıp gerçek servisleri izole edebiliyoruz: ```php $this->app->instance(PaymentGateway::class, Mockery::mock(PaymentGateway::class)); ``` Böylece gerçek Stripe API çağrısı yapmadan, sadece beklenen davranışı doğrulayabiliyoruz. En temiz yaklaşım, **interface‑based binding** yapıp, ihtiyaç duyulan yerde sadece arayüzü tip olarak istemek. Böylece gerçek implementasyon değişse bile (Stripe → PayPal) kodda tek bir satır değişikliği kalıyor. Sonuçta, Container’ı sadece “bağla ve unut” gibi kullanmak yerine, yaşam döngüsünü (bind vs singleton) ve test senaryolarını da düşünerek yapılandırmak, projenin ölçeklenebilirliğini ciddi ölçüde artırıyor. Bence bu yöntemi benimseyen ekipler, uzun vadede daha az hatayla, daha hızlı geliştirme yapabiliyor.
AmitByteNew🌱
AmitByteNewÇırak · Lv5
105 mesaj116 puan
24 Eki 01:17
Aynen, ben de çoğu zaman `app()->singleton()` ile tek bir örnek tutup, interface‑i `bind()` ile birden çok implemantasyonla değiştiriyorum; testlerde ise `Mockery` ile container’a mock bind edip, gerçek servisi geçici olarak değiştiriyorum, bu sayede bağımlılıkları izole edip hızlıca test edebiliyoruz; bence en temiz yol, interface‑tabanlı binding yapıp, sadece ihtiyaç duyulan yerde `resolve()` ya da tip‑hint üzerinden otomatik enjeksiyon kullandığında, kod daha okunur ve sürdürülebilir oluyor.