Gereksinimler ve Ön Hazırlık
Bu rehberi uygulamak için sisteminizde Laravel 11 veya üzeri bir sürümün kurulu olması gerekmektedir. Bağımlılık yönetimi için Composer'ın güncel olduğundan emin olun. Çalışma ortamınızda PHP 8.2 veya daha yeni bir sürümün bulunması, modern sözdizimi özelliklerini kullanabilmeniz açısından zorunludur.
- Laravel 11+ yüklü bir proje
- PHP 8.2+ sürümü
- Composer paket yöneticisi
- Temel düzeyde Dependency Injection (Bağımlılık Enjeksiyonu) bilgisi
Servis Sağlayıcı Oluşturma Adımları
Laravel'de bir servis sağlayıcı oluşturmak için Artisan komut satırı aracını kullanmak en hızlı ve güvenli yoldur. Bu işlem, gerekli dosya yapısını otomatik olarak oluşturur.
php artisan make:provider PaymentServiceProvider
Yukarıdaki komut, app/Providers dizini altında PaymentServiceProvider.php dosyasını oluşturur. Bu sınıf içerisinde iki temel metod bulunur: register ve boot. register metodu sadece bağlamalar (bindings) için, boot metodu ise bağlamalar yapıldıktan sonra çalıştırılacak işlemler için kullanılır.
Bağımlılıkları Servis Konteynerine Bağlama
Servis sağlayıcının temel amacı, bir sınıfın örneğini (instance) Laravel'in servis konteynerine tanıtmaktır. Örneğin, bir ödeme geçidi sınıfını konteynere bağlayalım.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Services\PaymentGateway;
class PaymentServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(PaymentGateway::class, function ($app) {
return new PaymentGateway(config('services.payment.key'));
});
}
}
Burada singleton metodu kullanılmıştır. Bu, sınıfın uygulama yaşam döngüsü boyunca sadece bir kez oluşturulmasını ve her çağrıldığında aynı örneğin dönmesini sağlar. config() yardımcısı ile yapılandırma dosyasından API anahtarını güvenli bir şekilde çekiyoruz.
Servis Sağlayıcıyı Kaydetme
Oluşturduğunuz sağlayıcının Laravel tarafından tanınması için bootstrap/providers.php dosyasına eklenmesi gerekir. Laravel 11 ile birlikte bu dosya, servis sağlayıcıları merkezi olarak yönetmenizi sağlar.
return [
App\Providers\AppServiceProvider::class,
App\Providers\PaymentServiceProvider::class,
];
Bu adım, uygulamanızın her açılışında PaymentServiceProvider sınıfının register metodunun tetiklenmesini garanti eder. Eğer bu adımı atlarsanız, sınıfınız konteyner tarafından çözümlenemez (resolve edilemez).
Servisi Uygulama İçinde Kullanma
Servis sağlayıcıyı başarıyla kaydettikten sonra, artık bağımlılık enjeksiyonunu kullanarak sınıfınızı herhangi bir Controller veya Service sınıfında kullanabilirsiniz.
namespace App\Http\Controllers;
use App\Services\PaymentGateway;
use Illuminate\Http\Request;
class CheckoutController extends Controller
{
public function __construct(protected PaymentGateway $paymentGateway) {}
public function process(Request $request)
{
return $this->paymentGateway->charge($request->amount);
}
}
Bu örnekte, PaymentGateway sınıfı otomatik olarak konteynerden çözümlenir (Type-hinting). Bu, kodunuzun test edilebilirliğini artırır ve doğrudan sınıfın yeni bir örneğini oluşturma zorunluluğunu ortadan kaldırır.
Servis Sağlayıcı Yöntemlerinin Karşılaştırması
Servisleri konteynere bağlarken farklı yöntemler mevcuttur. İhtiyacınıza göre en uygun olanı seçmeniz performans ve bellek yönetimi açısından kritiktir.
| Yöntem | Açıklama | Kullanım Durumu |
|---|---|---|
singleton |
Her çağrıda aynı örneği döner. | Veritabanı bağlantıları, API istemcileri. |
bind |
Her çağrıda yeni bir örnek oluşturur. | Durum tutmayan, hafif sınıflar. |
instance |
Mevcut bir nesneyi konteynere bağlar. | Dışarıdan gelen hazır nesneler. |
Kritik Güvenlik Uyarısı: Servis sağlayıcılarınızda asla hassas API anahtarlarını veya veritabanı şifrelerini doğrudan kod içerisine (hard-coded) yazmayın. Her zaman.envdosyasını veconfig/dizinindeki yapılandırma dosyalarını kullanın. Ayrıca, üretim ortamında (production) servis sağlayıcılarınızın önbelleğe alınmış olduğundan emin olmak içinphp artisan config:cachekomutunu düzenli olarak çalıştırın.
Sıkça Sorulan Sorular
Servis sağlayıcılar neden gereklidir?
Servis sağlayıcılar, uygulamanın farklı bölümlerini birbirine bağlayan "yapıştırıcı" görevi görür. Bağımlılıkların yönetilmesini, sınıfların yapılandırılmasını ve uygulamanın başlatılma mantığının ayrıştırılmasını sağlar.
Register ve Boot metodu arasındaki fark nedir?
register metodu sadece nesneleri konteynere bağlamak için kullanılmalıdır. boot metodu ise tüm servislerin kaydedildiği varsayılarak, olay dinleyicileri (event listeners) veya rotalar gibi bağımlılıkların kullanılabilir olduğu aşamada çalışır.
Servis sağlayıcıyı ne zaman kullanmalıyım?
Projenizde bir sınıfın başka sınıflara bağımlı olduğu veya karmaşık bir nesne oluşturma mantığına ihtiyaç duyduğunuz her durumda servis sağlayıcıları tercih etmelisiniz.
Bağımlılık enjeksiyonu (DI) hata verirse ne yapmalıyım?
Genellikle sınıfın bootstrap/providers.php dosyasında kayıtlı olmadığını veya sınıfın namespace yolunun yanlış olduğunu gösterir. php artisan route:clear ve php artisan config:clear komutlarını çalıştırarak önbelleği temizlemeyi deneyin.
Servis sağlayıcılar uygulama performansını etkiler mi?
Çok sayıda servis sağlayıcı eklemek, uygulamanın her isteğinde bu sınıfların yüklenmesine neden olur. Ancak, deferred (ertelenmiş) servis sağlayıcılar kullanarak sadece ihtiyaç duyulduğunda yüklenmelerini sağlayarak performansı optimize edebilirsiniz.
İleri Seviye Optimizasyon: Ertelenmiş (Deferred) Servis Sağlayıcılar
Uygulamanız büyüdükçe, her istekte (request) tüm servis sağlayıcıların yüklenmesi performans kaybına neden olabilir. Laravel, yalnızca ihtiyaç duyulduğunda yüklenen "ertelenmiş" servis sağlayıcıları destekler. Bu, uygulamanızın açılış süresini ciddi oranda iyileştirir.
Bir servis sağlayıcıyı ertelenmiş hale getirmek için Illuminate\Contracts\Support\DeferrableProvider arayüzünü implement etmeniz ve provides metodunu tanımlamanız yeterlidir.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Support\DeferrableProvider;
use App\Services\PaymentGateway;
class PaymentServiceProvider extends ServiceProvider implements DeferrableProvider
{
public function register()
{
$this->app->singleton(PaymentGateway::class, function ($app) {
return new PaymentGateway(config('services.payment.key'));
});
}
public function provides()
{
return [PaymentGateway::class];
}
}
Bu yapılandırma ile Laravel, PaymentGateway sınıfı kod içerisinde çağrılana kadar register metodunu çalıştırmayacaktır. Bu da gereksiz bellek kullanımını engeller.
Servis Sağlayıcılar İçin Birim Testleri (Unit Testing)
Servis sağlayıcılarınızın düzgün çalışıp çalışmadığını test etmek, uygulamanın kararlılığı için kritiktir. Servis konteynerine doğru sınıfın bağlanıp bağlanmadığını doğrulamak için Laravel'in yerleşik test araçlarını kullanabilirsiniz.
Aşağıdaki örnekte, servis konteynerinde PaymentGateway sınıfının başarıyla çözülüp çözülmediğini test ediyoruz:
public function test_payment_gateway_is_bound_in_container()
{
$gateway = $this->app->make(\App\Services\PaymentGateway::class);
$this->assertInstanceOf(\App\Services\PaymentGateway::class, $gateway);
}
Hata Ayıklama İpuçları
- Konteyner Dökümü: Eğer bir servisin neden yüklenmediğini anlamıyorsanız,
dd($this->app->getBindings())komutu ile o anki tüm kayıtlı servisleri listeleyebilirsiniz. - Cache Temizliği: Servis sağlayıcı değişiklikleri bazen Laravel'in konfigürasyon önbelleğine takılabilir. Değişiklikleriniz yansımıyorsa
php artisan config:clearkomutunu çalıştırmayı unutmayın. - Namespace Hataları: Servis sağlayıcınızı
config/app.phpdosyasında tanımlarken tam namespace yolunu (Full Qualified Class Name) kullandığınızdan emin olun.
Profesyonel Not: Servis sağlayıcılarınızda asla doğrudan veritabanı sorgusu yapmayın veya ağır dosya sistemi işlemleri gerçekleştirmeyin. Bu tür işlemler, uygulamanın her sayfa yüklenişinde yavaşlamasına neden olur. Eğer veritabanı verisine ihtiyacınız varsa, bunu boot metodu içerisinde veya servis çağrıldığında (lazy loading) yapın.
Sonuç
Laravel'de özel bir servis sağlayıcı entegrasyonu yapmak, uygulamanızın mimarisini profesyonel bir seviyeye taşımanın en etkili yoludur. Bu rehberde öğrendiğiniz yöntemler, bağımlılıkları merkezi bir şekilde yönetmenize ve kodunuzun test edilebilirliğini artırmanıza olanak tanır. Bir sonraki adım olarak, büyük ölçekli uygulamalarda servis sağlayıcılarınızı deferred (ertelenmiş) olarak işaretleyerek uygulamanızın açılış hızını nasıl daha da optimize edebileceğinizi araştırmanızı öneririm.
Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Yazılım geliştirme süreçlerinde güvenlik, her zaman geliştiricinin sorumluluğundadır. Uygulamanızın güvenliği için her zaman en güncel güvenlik yamalarını takip edin ve kullanıcı girdilerini mutlaka doğrulayın.

Yorumlar (0)
Yorum Yaz