Skip to main content

NestJS Bağımlılık Enjeksiyonu (DI) Rehberi: Neden ve Nasıl Kullanılır? 🚀

Meta Açıklaması: NestJS projelerinizde Bağımlılık Enjeksiyonu (DI) prensibini, temel dekoratörleri ve Kontrolün Tersine Çevrilmesi (IoC) mekanizmasını kullanarak modüler uygulamalar geliştirin.


📘 Bu Rehberde Ne Öğreneceksiniz

  • Bağımlılık Enjeksiyonu (Dependency Injection) kavramını ve NestJS’te nasıl uygulandığını.
  • IoC (Kontrolün Tersine Çevrilmesi) mekanizmasının mantığını.
  • @Injectable(), @Module(), @Controller() gibi temel NestJS dekoratörlerinin rollerini.
  • Bağımlılık çözümleme hatalarının nasıl giderileceğini.

1️⃣ Bağımlılık Enjeksiyonu (DI) Kavramı

Bağımlılık Enjeksiyonu (Dependency Injection), bir sınıfın ihtiyaç duyduğu bağımlılıkların dışarıdan sağlanması prensibidir.
Bu sayede, bir sınıf başka bir sınıfın örneğini kendisi oluşturmak yerine dışarıdan alır.

NestJS, bu deseni temel alarak sıkı bağlı (tightly coupled) yapıları gevşek bağlı (loosely coupled) hale getirir.


🔒 DI Olmadan Sıkı Bağlılık Örneği

Bu örnek, bağımlılığın doğrudan oluşturulduğu klasik yapıyı gösterir.

// Kendi bağımlılığını kendi oluşturuyor.
class VeriTabanıServisi {
baglan() {
console.log(`Veritabanı bağlantısı başlatıldı.`);
}
}

class MakaleServisi {
constructor() {
this.vtServisi = new VeriTabanıServisi(); // Sıkı Bağlılık
}

makaleOlustur(baslik) {
return this.vtServisi.olustur(baslik);
}
}

Bu örnekte MakaleServisi, VeriTabanıServisi’ne doğrudan bağımlıdır. Veritabanı türü değiştiğinde bu kodu da değiştirmek gerekir.

🧩 NestJS ile Gevşek Bağlılık

Bu örnek, NestJS’in DI konteynerinin sınıfları otomatik olarak enjekte etmesini gösterir.


import { Injectable } from '@nestjs/common';

@Injectable()
class VeriTabanıServisi {
kaydet(veri) {
console.log(`"${veri.baslik}" başlıklı makale kaydedildi.`);
}
}

@Injectable()
class MakaleServisi {
constructor(private vtServisi: VeriTabanıServisi) {} // Yapıcı Enjeksiyonu

makaleOlustur(baslik, icerik) {
this.vtServisi.kaydet({ baslik, icerik });
}
}

Bu örnekte, MakaleServisi artık new kullanmaz. Bağımlılık (vtServisi), yapıcı (constructor) aracılığıyla otomatik olarak enjekte edilir. NestJS, bu sınıfları DI konteyneri üzerinden yönetir.


2️⃣ Kontrolün Tersine Çevrilmesi (IoC)

IoC (Inversion of Control), NestJS’in bağımlılıkları yönetmek için kullandığı mimari prensiptir. Geleneksel akışta program nesnelerin akışını kontrol ederken, IoC’de bu kontrolü NestJS üstlenir.

Kısaca:

Kodun bağımlılıkları çağırmak yerine, NestJS bağımlılıkları sana getirir.

NestJS’in IoC Konteyneri, tüm sağlayıcıların (providers) oluşturulmasını ve yaşam döngüsünü yönetir. Bu, uygulamanı daha modüler, test edilebilir ve ölçeklenebilir hale getirir.

💡 Örnek akış: AppModule → OyuncularModulu → OyuncuServisi → OyuncularDenetleyici Bu zincirde NestJS, önce provider’ları oluşturur, sonra controller’a enjekte eder.


3️⃣ NestJS’teki Temel Dekoratörler ve Rolleri

NestJS, uygulamanın yapısını tanımlamak için TypeScript Dekoratörleri (Decorators) kullanır. Dekoratörler, sınıfların DI konteyneri tarafından nasıl ele alınacağını belirler.

🧱 A. @Injectable()

Bir sınıfın NestJS DI sistemi tarafından yönetilebileceğini belirtir.


import { Injectable } from '@nestjs/common';

@Injectable()
export class OyuncuServisi {
getOyuncular() {
return [
{ id: 1, ad: 'Lionel Messi' },
{ id: 2, ad: 'Cristiano Ronaldo' },
];
}
}

Bu dekoratör, sınıfı sağlayıcı (provider) haline getirir. NestJS, bu sınıfın örneğini kendi konteynerinde oluşturur ve diğer bileşenlere enjekte eder.

🎮 B. @Controller()

Bir sınıfı HTTP isteklerini işleyen denetleyici (controller) olarak tanımlar.


import { Controller, Get } from '@nestjs/common';
import { OyuncuServisi } from './oyuncu.servisi';

@Controller('oyuncular')
export class OyuncularDenetleyici {
constructor(private readonly oyuncuServisi: OyuncuServisi) {}

@Get()
getOyuncular() {
return this.oyuncuServisi.getOyuncular();
}
}

NestJS, denetleyiciyi oluşturduğunda OyuncuServisi’ni otomatik olarak enjekte eder. Böylece GET /oyuncular isteği çağrıldığında, servis veriyi döner.

🧩 C. @Module()

Uygulamanın yapı taşlarını organize eder: controller’lar, provider’lar ve import edilen modüller.


import { Module } from '@nestjs/common';
import { OyuncularDenetleyici } from './oyuncular.den';
import { OyuncuServisi } from './oyuncu.servisi';

@Module({
controllers: [OyuncularDenetleyici],
providers: [OyuncuServisi],
})
export class OyuncularModulu {}

NestJS uygulaması başlatıldığında @Module() metadata’sına bakar. providers dizisindeki sınıfların örneklerini oluşturur, controllers dizisindeki bileşenlere enjekte eder.

⚠️ Hata Giderme: “Bağımlılık Çözümlenemiyor” Hatası Yeni başlayanlarda sık görülen hata:


@Module({
controllers: [OyuncularDenetleyici],
providers: [], // OyuncuServisi eksik!
})
export class OyuncularModulu {}

Bu durumda NestJS şu hatayı verir:

❌ Can't resolve dependency of OyuncularDenetleyici.

✅ Çözüm:

Kullanılan sağlayıcının (OyuncuServisi), ilgili modülün providers dizisinde tanımlandığından emin olun.


❓ Sıkça Sorulan Sorular (SSS)

  1. DI kullanmanın faydaları nelerdir?

Bağımlılık Enjeksiyonu kodun gevşek bağlı olmasını sağlar, test etmeyi kolaylaştırır. Bağımlılıkları mock’layarak birim testleri hızla çalıştırabilirsiniz.

  1. NestJS'te @Injectable() ne zaman kullanılmalı?

Bir sınıf başka bir sınıf tarafından kullanılacaksa (örneğin servisler) mutlaka @Injectable() ile işaretlenmelidir.

  1. Dekoratörler ne işe yarar?

Dekoratörler, sınıfların NestJS tarafından nasıl yönetileceğini belirleyen metadata sağlar. Yani NestJS hangi sınıfın provider, hangisinin controller olduğunu bu bilgilerle bilir.

  1. imports dizisi ne işe yarar?

imports, başka bir modülün dışa aktardığı provider’lara erişim sağlar. Yani bir modül import edildiğinde, sadece export edilen bileşenlere erişebilirsiniz.


🏁 Sonuç

Bu rehberde, NestJS’in Bağımlılık Enjeksiyonu (DI) sistemini ve IoC konteynerinin nasıl çalıştığını öğrendiniz. Ayrıca temel dekoratörleri kullanarak modüler, esnek ve test edilebilir uygulamalar oluşturmayı keşfettiniz.

🚀 Bu teknikleri Rabisu Bulut projelerinizde hemen deneyebilirsiniz!