Diferença entre Dependency Injection e Service Locator em C#

Diferença entre Dependency Injection e Service Locator A injeção de dependência (Dependency Injection - DI) e o localizador de serviço (Service Locator - SL) são padrões utilizados para gerenciar dependências em aplicações C#. Ambos ajudam a desacoplar componentes, mas funcionam de maneiras diferentes. Dependency Injection (DI) A Dependency Injection é um padrão que permite que dependências sejam passadas para uma classe em vez de serem instanciadas dentro dela. Isso melhora a testabilidade, manutenção e extensibilidade do código. Exemplo de Dependency Injection // Interface do Serviço public interface IEmailService { void SendEmail(string message); } // Implementação do Serviço public class EmailService : IEmailService { public void SendEmail(string message) { Console.WriteLine($"Email enviado: {message}"); } } // Classe que recebe a dependência via construtor public class NotificationService { private readonly IEmailService _emailService; public NotificationService(IEmailService emailService) { _emailService = emailService; } public void Notify(string message) { _emailService.SendEmail(message); } } // Configuração do Dependency Injection var serviceProvider = new ServiceCollection() .AddScoped() .BuildServiceProvider(); // Resolvendo a dependência var notificationService = new NotificationService(serviceProvider.GetRequiredService()); notificationService.Notify("Olá, DI!"); Service Locator (SL) O padrão Service Locator usa um contêiner global para gerenciar e recuperar dependências. Embora facilite a resolução dinâmica de serviços, pode dificultar testes e depuração, pois cria um forte acoplamento com o contêiner de injeção. Exemplo de Service Locator public static class ServiceLocator { private static IServiceProvider _serviceProvider; public static void SetLocator(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public static T GetService() => _serviceProvider.GetRequiredService(); } // Configuração do contêiner var serviceProvider = new ServiceCollection() .AddScoped() .BuildServiceProvider(); ServiceLocator.SetLocator(serviceProvider); // Resolvendo a dependência via Service Locator var emailService = ServiceLocator.GetService(); emailService.SendEmail("Olá, SL!"); Comparando Dependency Injection e Service Locator Critério Dependency Injection Service Locator Acoplamento Baixo Alto Testabilidade Melhor Difícil Facilidade de uso Pode requerer configuração Fácil de usar Manutenção Melhor para evolução Pode dificultar depuração Snippet Exclusivo - Comparando os Dois Padrões public class Program { public static void Main() { var services = new ServiceCollection() .AddScoped() .BuildServiceProvider(); // Dependency Injection var notificationServiceDI = new NotificationService(services.GetRequiredService()); notificationServiceDI.Notify("Usando Dependency Injection"); // Service Locator ServiceLocator.SetLocator(services); var emailServiceSL = ServiceLocator.GetService(); emailServiceSL.SendEmail("Usando Service Locator"); } } Conclusão Embora ambos os padrões possam ser usados, a Dependency Injection é preferida por proporcionar menor acoplamento e maior testabilidade. O Service Locator pode ser útil em cenários específicos, mas seu uso excessivo pode levar a dificuldades na manutenção do código. Escolha o padrão que melhor atende às necessidades do seu projeto!

Mar 21, 2025 - 14:08
 0
Diferença entre Dependency Injection e Service Locator em C#

Diferença entre Dependency Injection e Service Locator

A injeção de dependência (Dependency Injection - DI) e o localizador de serviço (Service Locator - SL) são padrões utilizados para gerenciar dependências em aplicações C#. Ambos ajudam a desacoplar componentes, mas funcionam de maneiras diferentes.

Dependency Injection (DI)

A Dependency Injection é um padrão que permite que dependências sejam passadas para uma classe em vez de serem instanciadas dentro dela. Isso melhora a testabilidade, manutenção e extensibilidade do código.

Exemplo de Dependency Injection

// Interface do Serviço
public interface IEmailService
{
    void SendEmail(string message);
}

// Implementação do Serviço
public class EmailService : IEmailService
{
    public void SendEmail(string message)
    {
        Console.WriteLine($"Email enviado: {message}");
    }
}

// Classe que recebe a dependência via construtor
public class NotificationService
{
    private readonly IEmailService _emailService;

    public NotificationService(IEmailService emailService)
    {
        _emailService = emailService;
    }

    public void Notify(string message)
    {
        _emailService.SendEmail(message);
    }
}

// Configuração do Dependency Injection
var serviceProvider = new ServiceCollection()
    .AddScoped<IEmailService, EmailService>()
    .BuildServiceProvider();

// Resolvendo a dependência
var notificationService = new NotificationService(serviceProvider.GetRequiredService<IEmailService>());
notificationService.Notify("Olá, DI!");

Service Locator (SL)

O padrão Service Locator usa um contêiner global para gerenciar e recuperar dependências. Embora facilite a resolução dinâmica de serviços, pode dificultar testes e depuração, pois cria um forte acoplamento com o contêiner de injeção.

Exemplo de Service Locator

public static class ServiceLocator
{
    private static IServiceProvider _serviceProvider;

    public static void SetLocator(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public static T GetService<T>() => _serviceProvider.GetRequiredService<T>();
}

// Configuração do contêiner
var serviceProvider = new ServiceCollection()
    .AddScoped<IEmailService, EmailService>()
    .BuildServiceProvider();

ServiceLocator.SetLocator(serviceProvider);

// Resolvendo a dependência via Service Locator
var emailService = ServiceLocator.GetService<IEmailService>();
emailService.SendEmail("Olá, SL!");

Comparando Dependency Injection e Service Locator

Critério Dependency Injection Service Locator
Acoplamento Baixo Alto
Testabilidade Melhor Difícil
Facilidade de uso Pode requerer configuração Fácil de usar
Manutenção Melhor para evolução Pode dificultar depuração

Snippet Exclusivo - Comparando os Dois Padrões

public class Program
{
    public static void Main()
    {
        var services = new ServiceCollection()
            .AddScoped<IEmailService, EmailService>()
            .BuildServiceProvider();

        // Dependency Injection
        var notificationServiceDI = new NotificationService(services.GetRequiredService<IEmailService>());
        notificationServiceDI.Notify("Usando Dependency Injection");

        // Service Locator
        ServiceLocator.SetLocator(services);
        var emailServiceSL = ServiceLocator.GetService<IEmailService>();
        emailServiceSL.SendEmail("Usando Service Locator");
    }
}

Conclusão

Embora ambos os padrões possam ser usados, a Dependency Injection é preferida por proporcionar menor acoplamento e maior testabilidade. O Service Locator pode ser útil em cenários específicos, mas seu uso excessivo pode levar a dificuldades na manutenção do código. Escolha o padrão que melhor atende às necessidades do seu projeto!