Sobes.tech
Middle+

Czym jest lokalizator usług?

sobes.tech AI

Odpowiedź od AI

Service Locator to wzorzec projektowy, który zapewnia globalny punkt dostępu do usług (obiektów wykonujących określone zadania), nie wymagając od kodu klienta znajomości konkretnych typów implementacji tych usług. Encapsuluje proces uzyskiwania potrzebnej usługi.

Zalety Service Locator:

  • Zcentralizowany dostęp: Ułatwia dostęp do usług z dowolnego miejsca w aplikacji.
  • Elastyczność: Umożliwia łatwą zmianę implementacji usług bez modyfikacji kodu klienta.

Wady Service Locator (główny powód krytyki):

  • Ukryte zależności: Kod klienta nie deklaruje jawnie swoich zależności, co utrudnia zrozumienie, jakie usługi są potrzebne.
  • Testowalność: Trudno testować klasy korzystające z Service Locator, ponieważ zależności nie mogą być łatwo podmienione (mockowane).
  • Naruszenie zasady odwrócenia zależności (DIP): Zamiast uzyskiwać zależności przez konstruktor lub właściwości, klasa aktywnie ich żąda.
  • Trudności z zarządzaniem cyklem życia: Service Locator często nie potrafi zarządzać cyklem życia zarejestrowanych usług (np. tworzyć singletony lub obiekty transient).

Przykład prostej implementacji:

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($"Usługa typu {typeof(TService).Name} już zarejestrowana.");
        }
        _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($"Usługa typu {typeof(TService).Name} nie znaleziona.");
    }
}

Przykład użycia:

// Rejestracja usługi
ServiceLocator.RegisterService<ILogger>(new ConsoleLogger());

// Uzyskanie usługi
ILogger logger = ServiceLocator.GetService<ILogger>();
logger.LogInfo("Hello, Service Locator!");

W nowoczesnym rozwoju C# Service Locator jest często zastępowany przez użycie kontenerów Inversion of Control (IoC), które zapewniają pełną Dependency Injection (DI), co jest bardziej preferowanym podejściem do zarządzania zależnościami i poprawy testowalności kodu. Kontenery IoC pozwalają na jawne deklarowanie zależności i automatyczne ich wstrzykiwanie, zgodnie z zasadami DIP.