Sobes.tech
Middle+

Какво е сервис локатор?

sobes.tech AI

Отговор от AI

Service Locator е шаблон за проектиране, който предоставя глобална точка за достъп до услуги (обекти, изпълняващи определени задачи), без клиентският код да трябва да знае конкретните типове на реализациите на тези услуги. Той капсулира процеса на получаване на необходимата услуга.

Предимства на Service Locator:

  • Централизиран достъп: Улеснява получаването на услуги от всяко място в приложението.
  • Гъвкавост: Позволява лесно да се променят реализациите на услугите без да се променя клиентският код.

Недостатъци на Service Locator (основната причина за критика):

  • Скрити зависимости: Клиентският код не обявява явно своите зависимости, което усложнява разбирането кои услуги са необходими.
  • Тестване: Трудно е да се тестират класове, използващи Service Locator, тъй като зависимостите не могат лесно да бъдат заместени (mocked).
  • Нарушение на принципа за инверсия на зависимостите (DIP): Вместо да получава зависимости чрез конструктор или свойства, класът активно ги изисква.
  • Трудности при управление на жизнения цикъл: Service Locator често не може да управлява жизнения цикъл на регистрираните услуги (например, създаване на singleton-и или transient обекти).

Пример за проста реализация:

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($"Service of type {typeof(TService).Name} вече е регистрирана.");
        }
        _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($"Service of type {typeof(TService).Name} не е намерена.");
    }
}

Пример за използване:

// Регистрация на услуга
ServiceLocator.RegisterService<ILogger>(new ConsoleLogger());

// Получаване на услуга
ILogger logger = ServiceLocator.GetService<ILogger>();
logger.LogInfo("Hello, Service Locator!");

В съвременната разработка на C# Service Locator често се заменя с използването на IoC контейнери, които предоставят пълноценна Dependency Injection (DI), което е по-препоръчителен подход за управление на зависимостите и подобряване на тестируемостта на кода. IoC контейнерите позволяват явно да се обявяват зависимостите и автоматично да ги внедряват, следвайки принципите на DIP.