Sobes.tech
Middle+

O que é um localizador de serviços?

sobes.tech IA

Resposta da IA

Service Locator é um padrão de design que fornece um ponto de acesso global aos serviços (objetos que realizam tarefas específicas), sem exigir que o código cliente conheça os tipos específicos de implementação desses serviços. Ele encapsula o processo de obtenção do serviço necessário.

Vantagens do Service Locator:

  • Acesso centralizado: Facilita a obtenção de serviços de qualquer parte da aplicação.
  • Flexibilidade: Permite alterar facilmente as implementações dos serviços sem modificar o código cliente.

Desvantagens do Service Locator (a principal razão das críticas):

  • Dependências ocultas: O código cliente não declara explicitamente suas dependências, dificultando a compreensão de quais serviços são necessários.
  • Testabilidade: É difícil testar classes que usam Service Locator, pois as dependências não podem ser facilmente substituídas (mocked).
  • Violação do princípio de inversão de dependências (DIP): Em vez de obter dependências através do construtor ou propriedades, a classe as solicita ativamente.
  • Dificuldades na gestão do ciclo de vida: O Service Locator muitas vezes não consegue gerenciar o ciclo de vida dos serviços registrados (por exemplo, criar singleton ou objetos transitórios).

Exemplo de implementação simples:

public static class ServiceLocator
{
    private static Dictionary<Type, object> _services = new Dictionary<Type, object>();

    public static void RegisterService<TService>(TService serviceInstance) where TService : class
    {
        if (_services.ContainsKey(typeof(TService)))
        {
            throw new InvalidOperationException($"Serviço do tipo {typeof(TService).Name} já registrado.");
        }
        _services[typeof(TService)] = serviceInstance;
    }

    public static TService GetService<TService>() where TService : class
    {
        if (_services.TryGetValue(typeof(TService), out object service))
        {
            return (TService)service;
        }
        throw new InvalidOperationException($"Serviço do tipo {typeof(TService).Name} não encontrado.");
    }
}

Exemplo de uso:

// Registo do serviço
ServiceLocator.RegisterService<ILogger>(new ConsoleLogger());

// Obtenção do serviço
ILogger logger = ServiceLocator.GetService<ILogger>();
logger.LogInfo("Hello, Service Locator!");

No desenvolvimento moderno em C#, o Service Locator é frequentemente substituído pelo uso de contêineres de Inversão de Controle (IoC), que fornecem uma injeção de dependências (DI) completa, sendo esta uma abordagem mais recomendada para gerenciar dependências e melhorar a testabilidade do código. Os contêineres IoC permitem declarar explicitamente as dependências e injetá-las automaticamente, seguindo os princípios de DIP.