Skip to content

Dependency Injection

Genel Bakış

Dependency Injection (DI), nesnelerin bağımlılıklarını dışarıdan almasını sağlayan bir tasarım desenidir. ASP.NET Core'da built-in DI container bulunur ve bu sayede loose coupling, test edilebilirlik ve modülerlik sağlanır.

Mülakat Soruları ve Cevapları

1. Dependency Injection nedir ve neden kullanılır?

Cevap: Dependency Injection, bir nesnenin bağımlılıklarının dışarıdan verilmesi prensibidir. Kullanım nedenleri: - Loose coupling sağlar - Test edilebilirliği artırır - Kod bakımını kolaylaştırır - Modüler yapıyı destekler

Örnek Kod:

// DI kullanmadan
public class UserService
{
    private readonly UserRepository _repository = new UserRepository();
}

// DI ile
public class UserService
{
    private readonly IUserRepository _repository;

    public UserService(IUserRepository repository)
    {
        _repository = repository;
    }
}

2. Service lifetimes nelerdir?

Cevap: ASP.NET Core'da üç farklı service lifetime vardır: - Singleton: Uygulama yaşam döngüsü boyunca tek instance - Scoped: Her HTTP isteği için yeni instance - Transient: Her servis talebinde yeni instance

Örnek Kod:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ICacheService, CacheService>();
    services.AddScoped<IUserService, UserService>();
    services.AddTransient<IEmailService, EmailService>();
}

3. Constructor injection ve method injection arasındaki farklar nelerdir?

Cevap: Constructor injection: - Sınıf seviyesinde bağımlılık - Tüm metodlar için kullanılabilir - Daha yaygın kullanım - Test edilebilirlik açısından avantajlı

Method injection: - Metod seviyesinde bağımlılık - Sadece ilgili metod için kullanılır - Daha az yaygın - Geçici bağımlılıklar için uygun

Örnek Kod:

// Constructor injection
public class UserService
{
    private readonly IUserRepository _repository;

    public UserService(IUserRepository repository)
    {
        _repository = repository;
    }
}

// Method injection
public class UserService
{
    public void SendEmail(IEmailService emailService, string message)
    {
        emailService.Send(message);
    }
}

4. Service collection'a servis nasıl kaydedilir?

Cevap: Servisler ConfigureServices metodunda kaydedilir: - AddSingleton: Tek instance - AddScoped: Request başına instance - AddTransient: Her talepte instance - AddScoped vs AddTransient kullanım senaryoları

Örnek Kod:

public void ConfigureServices(IServiceCollection services)
{
    // Interface-implementation mapping
    services.AddScoped<IUserService, UserService>();

    // Concrete type
    services.AddSingleton<CacheService>();

    // Factory method
    services.AddTransient<IService>(sp => 
        new Service(sp.GetRequiredService<ILogger>()));
}

5. DI container'dan servis nasıl resolve edilir?

Cevap: Servisler şu yollarla resolve edilebilir: - Constructor injection (önerilen) - IServiceProvider kullanımı - [FromServices] attribute'u - ActivatorUtilities

Örnek Kod:

// Constructor injection
public class HomeController : Controller
{
    private readonly IUserService _userService;

    public HomeController(IUserService userService)
    {
        _userService = userService;
    }
}

// IServiceProvider
public class CustomMiddleware
{
    public async Task InvokeAsync(HttpContext context, IServiceProvider serviceProvider)
    {
        var service = serviceProvider.GetRequiredService<IService>();
    }
}

Best Practices

  1. Servis Kaydı
  2. Interface kullanın
  3. Doğru lifetime seçin
  4. Servisleri modüler tutun
  5. Circular dependency'den kaçının

  6. Performans

  7. Gereksiz servis kaydı yapmayın
  8. Singleton servisleri thread-safe yapın
  9. Memory leak'leri önleyin
  10. Dispose pattern'i uygulayın

  11. Test Edilebilirlik

  12. Mock'lanabilir servisler tasarlayın
  13. Interface'leri küçük tutun
  14. Bağımlılıkları minimize edin
  15. Unit test yazın

Kaynaklar