NodeJS ile Dependency Injection

NodeJS ile Dependency Injection

NodeJS'de Dependency Injection (Bağımlılık Enjeksiyonu) konusunu ele almak istedim. Bu kavram, başta kafa karıştırıcı görünse de, aslında çok faydalı ve güçlü bir araçtır.

Dependency Injection Nedir?

Kısaca açıklamak gerekirse, Dependency Injection, bir nesnenin bağımlılıklarını (yani ihtiyaç duyduğu diğer nesneleri veya modülleri) dışarıdan alması sürecidir. Böylece, kodumuz daha modüler, test edilebilir ve genişletilebilir hale gelir.

Örnek 1

Bir rest api uygulaması geliştirirken, genellikle veritabanı işlemleri için bir modül kullanırız. Diyelim ki, bir kullanıcı yönetimi modülümüz var ve bu modül, kullanıcıları veritabanına kaydetmek için bir veritabanı modülüne ihtiyaç duyar, ihtiyaç duyulan modülü Dependency Injection kullanarak bu bağımlılığı dışarıdan sağlayabiliriz.

// dbModule.js
class DBModule {
    constructor() {
    }

    saveUser(user) {
        // Veritabanı kayıt..
    }
}

module.exports = DBModule;

// userModule.js
class UserModule {
    constructor(dbModule) {
        this.dbModule = dbModule;
    }

    createUser(user) {
        this.dbModule.saveUser(user);
    }
}

// app.js
const DBModule = require('./dbModule');
const UserModule = require('./userModule');

const dbModule = new DBModule();
const userModule = new UserModule(dbModule);

userModule.createUser({ name: 'Ahmet', email: 'ahmet@example.com' });

Bu örnekte UserModule, DBModule'e doğrudan bağımlı değil. DBModule nesnesi, UserModule'a dışarıdan dahil ediliyor. Bu sayede, UserModule'ün veritabanı modülüne olan bağımlılığını kolayca değiştirebiliriz. Örneğin, farklı bir veritabanı modülü kullanmak istediğimizde, yalnızca app.js dosyasında değişiklik yapmamız yeterli olur.

Örnek 2

Diyelim bir E-Ticaret altyapısı yazıyorsunuz sipariş işlemleri için özel bir modülümüz (OrderModule) ve ödeme işlemleri için başka bir modülümüz (PaymentModule) var. Ödeme modülü, sipariş modülüne bağımlı çünkü ödeme işlemi, sipariş detaylarına ihtiyaç duyuyor.

Dependency Injection olmadan PaymentModule doğrudan OrderModule'a bağlı çalıştığını farz edin, projenin ilerleyen aşamalarında farklı ödeme servis sağlayıcılarını entegre etmek istediğimizde, bu bağımlılık sorun yaratır.. Her yeni ödeme yöntemi için OrderModule'de değişiklik yapmak gerekiyordu. İşte bu noktada Dependency Injection devreye girdi.

Öncelikle, eski yapıyı gösteren basit bir örnek:

// paymentModule.js 
const OrderModule = require('./orderModule');

class PaymentModule {
    processPayment(orderId) {
        const order = OrderModule.getOrder(orderId);
        // Ödeme işlemini gerçekleştir
    }
}

Yeni yapıda ise, OrderModule dışarıdan enjekte ediliyor:

// paymentModule.js
class PaymentModule {
    constructor(orderModule) {
        this.orderModule = orderModule;
    }

    processPayment(orderId) {
        const order = this.orderModule.getOrder(orderId);
        // Ödeme işlemini gerçekleştir
    }
}
const OrderModule = require('./orderModule');
const PaymentModule = require('./paymentModule');

const orderModule = new OrderModule();
const paymentModule = new PaymentModule(orderModule);

paymentModule.processPayment('12345');

Bu değişiklikle, PaymentModule artık OrderModule'e doğrudan bağımlı değil. Bu, farklı ödeme servis sağlayıcıları eklendiğinde veya OrderModule değiştiğinde, PaymentModule'ün esnek bir şekilde uyarlanabilmesini sağlıyor.

Sonuç

Dependency Injection, uygulamalarımızı daha esnek ve bakımı kolay hale getirir. Özellikle büyük ve karmaşık projelerde, bu yaklaşımın getirdiği avantajları net bir şekilde görebiliriz. Uygulamanızın farklı bölümlerini birbirinden bağımsız hale getirerek, kodunuzu daha sağlam ve yönetilebilir kılabilirsiniz. Umarım bu basit örnek, Dependency Injection'ın gücünü anlamanıza yardımcı olmuştur.