Ana içeriğe geç

Dependency Injection (DI)

Dependency Injection (DI), bir uygulamada bağımlılıkların yönetimini kolaylaştırarak test edilebilirliği ve kodun sürdürülebilirliğini artırır. Ancak DI yanlış kullanıldığında kodun karmaşıklığını artırabilir.


1. Bağımlılıkların Elle Yönetilmesi

Yanlış Kullanım: Bağımlılıkları elle örneklemek.

public class OrderService
{
    private readonly ProductRepository _productRepository;

    public OrderService()
    {
        _productRepository = new ProductRepository(); // Sıkı bağımlılık
    }
}

İdeal Kullanım: Bağımlılıkları bir IoC konteynırı üzerinden enjekte edin.

public class OrderService
{
    private readonly IProductRepository _productRepository;

    public OrderService(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }
}

2. Yanlış Yaşam Süresi (Lifetime) Yönetimi

Yanlış Kullanım: Scoped bağımlılıkları singleton bir hizmete enjekte etmek.

services.AddSingleton<MyService>();
services.AddScoped<MyDbContext>();

public class MyService
{
    private readonly MyDbContext _dbContext;

    public MyService(MyDbContext dbContext)
    {
        _dbContext = dbContext; // Hatalı yaşam süresi
    }
}

İdeal Kullanım: Bağımlılıkların yaşam süresini doğru yapılandırın.

services.AddScoped<MyService>();
services.AddScoped<MyDbContext>();

public class MyService
{
    private readonly MyDbContext _dbContext;

    public MyService(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }
}

3. Çok Fazla Bağımlılık Enjeksiyonu

Yanlış Kullanım: Bir sınıfta çok fazla bağımlılığı doğrudan enjekte etmek.

public class MyController
{
    public MyController(IService1 service1, IService2 service2, IService3 service3, IService4 service4)
    {
        // Çok fazla bağımlılık
    }
}

İdeal Kullanım: Bağımlılıkları gruplandırarak bir arayüz ile soyutlayın.

public interface IServiceGroup
{
    IService1 Service1 { get; }
    IService2 Service2 { get; }
}

public class ServiceGroup : IServiceGroup
{
    public IService1 Service1 { get; }
    public IService2 Service2 { get; }

    public ServiceGroup(IService1 service1, IService2 service2)
    {
        Service1 = service1;
        Service2 = service2;
    }
}

4. Service Locator Kullanımı

Yanlış Kullanım: Service locator anti-pattern’ini kullanmak.

public class MyService
{
    public void DoWork()
    {
        var service = ServiceLocator.GetService<IMyDependency>();
        service.PerformAction();
    }
}

İdeal Kullanım: Bağımlılıkları doğrudan enjekte edin.

public class MyService
{
    private readonly IMyDependency _myDependency;

    public MyService(IMyDependency myDependency)
    {
        _myDependency = myDependency;
    }

    public void DoWork()
    {
        _myDependency.PerformAction();
    }
}

5. Test Edilebilirliği Göz Ardı Etmek

Yanlış Kullanım: Sıkı bağımlılıklar nedeniyle test edilemeyen sınıflar.

public class ReportService
{
    private readonly Logger _logger = new Logger();

    public void GenerateReport()
    {
        _logger.Log("Rapor oluşturuluyor...");
    }
}

İdeal Kullanım: Logger gibi bağımlılıkları enjekte ederek test edilebilirliği artırın.

public class ReportService
{
    private readonly ILogger _logger;

    public ReportService(ILogger logger)
    {
        _logger = logger;
    }

    public void GenerateReport()
    {
        _logger.Log("Rapor oluşturuluyor...");
    }
}

6. Hizmetlerin Aşırı Kaydı

Yanlış Kullanım: Her bağımlılığı manuel olarak kaydetmek.

services.AddSingleton<IService1, Service1>();
services.AddSingleton<IService2, Service2>();
services.AddSingleton<IService3, Service3>();

İdeal Kullanım: Assembly tarama ile hizmetleri otomatik olarak kaydedin.

var assemblies = AppDomain.CurrentDomain.GetAssemblies();
services.Scan(scan => scan
    .FromAssemblies(assemblies)
    .AddClasses()
    .AsImplementedInterfaces()
    .WithScopedLifetime());