· Özgür Vurgun · NestJS · 2 min read

16. NestJS Mimarisi: Value, Class ve Factory Providers (14. Bölüm)

16. NestJS Mimarisi: Value, Class ve Factory Providers (14. Bölüm)

Provider Ne Demekti?

NestJS’de bir class veya değer, “provider” olarak tanımlanırsa constructor() içinde @Inject() ile enjekte edilebilir.

Yani dependency injection sistemine kayıtlı olur. Ama bu provider illa bir class olmak zorunda değil.

İşte tam burada 3 farklı yol devreye giriyor: TürNe Sağlar?Ne Zaman Kullanılır?Value ProviderSabit bir değer (obj, string, sayı)Config, sabit ayarlar, env verileriClass ProviderAlternatif class tanımıMock servis, farklı implementasyonlarFactory ProviderFonksiyonla üretilen providerDinamik yapı, config’e bağlı servis üretimi

1. Value Provider

Bir sabit değer sistemin bir parçası olarak kullanılır.

const config = {
  apiKey: 'abc123',
  baseUrl: 'https://api.example.com',
};
@Module({
  providers: [
    {
      provide: 'CONFIG',
      useValue: config,
    },
  ],
})
export class AppModule {}

Sabit verileri DI sistemine sokmanın en basit yolu

2. Class Provider

Normalde şöyle tanımlarız:

@Module({
  providers: [EmailService],
})

Ama eğer EmailService yerine farklı bir class kullanılacaksa:

@Module({
  providers: [
    {
      provide: EmailService,
      useClass: MockEmailService,
    },
  ],
})

Ya da string tokenla:

@Module({
  providers: [
    {
      provide: 'IEmailService',
      useClass: EmailService,
    },
  ],
})

Kullanımı:

constructor(@Inject('IEmailService') private emailService: EmailService) {}

Mocklama, test senaryosu, veya farklı implemantasyonlar için süper

3. Factory Provider

En güçlü ve esnek yöntem.

Provider’ı bir fonksiyonla oluşturursun. Yani runtime’da veriye göre ne döneceğine sen karar verirsin.

@Module({
  providers: [
    {
      provide: 'DATABASE_URL',
      useFactory: () => {
        return process.env.NODE_ENV === 'prod'
          ? 'mongodb://prod-db'
          : 'mongodb://localhost/dev';
      },
    },
  ],
})

Ve:

constructor(@Inject('DATABASE_URL') private dbUrl: string) {}

Dilersen başka dependency’ler de inject edebilirsin:

useFactory: (configService: ConfigService) => {
  return configService.get('databaseUrl');
},
inject: [ConfigService],

Dinamik yapı isteyenler için biçilmiş kaftan

Neden Bu Kadar Çeşit Var?

Çünkü NestJS sadece class değil, her şeyi DI container’a dahil edebilsin istiyor.

Bu sistemin sana sundukları:

  • Modülerlik
  • Mock edilebilirlik
  • Test kolaylığı
  • Ortam bazlı konfigürasyon desteği

TL;DR - Ne Ne İçin Kullanılır?

Provider TürüKullanım AmacıuseValueSabit bir değer sağlamak (env, config, sabit obj)useClassAlternatif implementasyonla inject etmekuseFactoryRuntime’da logic çalıştırarak provider oluşturmak

Gerçek Hayattan Senaryolar

  • useValue -> app.config.ts içinde ConfigService’e sabitler vermek
  • useClass -> Development ortamında MockMailService, production’da SendGridMailService
  • useFactory -> Request başına değişen servisler üretmek (örneğin tenant bazlı database bağlantısı)

Dikkat Edilecek Noktalar

  • provide: kısmı string ise @Inject('TOKEN') ile kullanılmalı
  • useClass, useValue, useFactory birbirinin yerine geçemez
  • Factory provider içinde başka servisler kullanılacaksa inject mutlaka tanımlanmalı
  • Provider’lar Module içinde tanımlanmazsa inject edilemez

Sonuç

  • NestJS provider sistemi sadece class’larla sınırlı değil
  • 3 farklı yol (value, class, factory) ihtiyaca göre çözüm sunar
  • Uygulamanın esnekliği ve sürdürülebilirliği bu yapılarla kurulur
  • Test yazmak, ortam yönetimi, configurasyon gibi konularda vazgeçilmezdir
Share:
Back to Blog

Related Posts

View All Posts »
17. NestJS Mimarisi: Provider Scope (15. Bölüm)

17. NestJS Mimarisi: Provider Scope (15. Bölüm)

Bir Servis, Herkes İçin Aynı mıdır? NestJS’te @Injectable() bir sınıf tanımladığında, varsayılan olarak bu servis singleton olur: Tüm uygulama boyunca sadece 1 kez oluşturulur ve...