← Back to Blog
TEKNIK

Dependency Injection Nedir?

F. Çağrı BilgehanJanuary 27, 202610 min read
dependency injectionsolidtasarım desenitest

Dependency Injection Nedir? Bağımlılık Enjeksiyonu Rehberi

Sınıflarınız birbirine sıkıca bağlı mı? Test yazmak zor mu? Veritabanını değiştirmek tüm kodu mu etkiliyor? Dependency Injection ile bağımlılıkları dışarıdan verin, esnek ve test edilebilir kod yazın.

DI Tanımı

Dependency Injection (DI), bir nesnenin bağımlılıklarını kendisi oluşturmak yerine dışarıdan alması prensibidir. SOLID'in D (Dependency Inversion) prensibinin pratik uygulamasıdır.

❌ DI Olmadan (Sıkı Bağlantı)

class OrderService {
  private db = new PostgresDatabase(); // Sıkı bağlantı!
  private mailer = new SmtpMailer();   // Değiştirmek zor!

  async placeOrder(order: Order) {
    await this.db.save(order);
    await this.mailer.send(order.customerEmail, 'Sipariş alındı');
  }
}

✅ DI İle (Gevşek Bağlantı)

interface Database {
  save(entity: any): Promise<void>;
}

interface Mailer {
  send(to: string, message: string): Promise<void>;
}

class OrderService {
  constructor(
    private db: Database,       // Dışarıdan veriliyor
    private mailer: Mailer      // Dışarıdan veriliyor
  ) {}

  async placeOrder(order: Order) {
    await this.db.save(order);
    await this.mailer.send(order.customerEmail, 'Sipariş alındı');
  }
}

DI Yöntemleri

1. Constructor Injection (Önerilen)

const db = new PostgresDatabase();
const mailer = new SmtpMailer();
const orderService = new OrderService(db, mailer);

2. Setter Injection

const service = new OrderService();
service.setDatabase(db);
service.setMailer(mailer);

3. Interface Injection

Bağımlılık bir interface aracılığıyla enjekte edilir.

Neden DI?

1. Test Edilebilirlik

// Test'te gerçek DB yerine mock kullan
class MockDatabase implements Database {
  saved: any[] = [];
  async save(entity: any) { this.saved.push(entity); }
}

class MockMailer implements Mailer {
  sent: string[] = [];
  async send(to: string, msg: string) { this.sent.push(to); }
}

test('placeOrder sipariş kaydeder ve e-posta gönderir', async () => {
  const mockDb = new MockDatabase();
  const mockMailer = new MockMailer();
  const service = new OrderService(mockDb, mockMailer);

  await service.placeOrder(testOrder);

  expect(mockDb.saved).toHaveLength(1);
  expect(mockMailer.sent).toContain('test@example.com');
});

2. Esneklik

// Geliştirme ortamı
const devService = new OrderService(new SqliteDatabase(), new ConsoleMailer());

// Üretim ortamı
const prodService = new OrderService(new PostgresDatabase(), new SmtpMailer());

3. Tek Sorumluluk

Her sınıf kendi işine odaklanır. Bağımlılıklarını oluşturmak onun işi değildir.

IoC Container

Büyük projelerde bağımlılıkları manuel yönetmek zordur. IoC Container bunu otomatikleştirir:

// NestJS örneği
@Injectable()
class OrderService {
  constructor(
    private readonly db: DatabaseService,
    private readonly mailer: MailerService,
  ) {}
}

@Module({
  providers: [OrderService, DatabaseService, MailerService],
})
class AppModule {}

Popüler IoC Container'lar

| Dil/Framework | Container | |--------------|-----------| | TypeScript | NestJS, InversifyJS, tsyringe | | Java | Spring | | C# | .NET DI, Autofac | | Python | dependency-injector |

DI Anti-Pattern'leri

  • Service Locator — Bağımlılığı global bir container'dan çekmek (gizli bağımlılık)
  • God Container — Her şeyi tek bir container'a koymak
  • Over-injection — Bir sınıfa 7+ bağımlılık enjekte etmek (SRP ihlali)
  • Concrete injection — Interface yerine somut sınıf enjekte etmek

Best Practices

  1. Interface'lere bağlanın — Somut sınıflara değil
  2. Constructor injection tercih edin — En açık ve test dostu yöntem
  3. Bağımlılık sayısını sınırlayın — 3-5 ideal, 7+ ise sınıfı bölün
  4. IoC container kullanın — Büyük projelerde manuel DI sürdürülemez
  5. Lifecycle yönetimi — Singleton vs transient vs scoped ayırımı yapın
  6. Circular dependency'den kaçının — A→B→A döngüsü tasarım hatasıdır

Sonuç

Dependency Injection, temiz, test edilebilir ve esnek kod yazmanın temelidir. Bağımlılıkları dışarıdan vererek sınıflarınızı birbirinden ayırırsınız. Küçük projelerde manuel DI yeterlidir; büyük projelerde IoC container kullanın.

Dependency Injection ve SOLID prensiplerini LabLudus platformunda öğrenin.

Related Posts

Acik Kaynak Yazilim Rehberi: Nedir, Nasil Katki Yapilir?

Acik kaynak yazilim nedir ve nasil katkida bulunulur?

CI/CD Nedir? Surekli Entegrasyon ve Dagitim Rehberi

CI/CD nedir ve nasil kurulur?