Sobes.tech
Middle+

Cos'è un localizzatore di servizi?

sobes.tech AI

Risposta dell'AI

Service Locator è un pattern di progettazione che fornisce un punto di accesso globale ai servizi (oggetti che eseguono compiti specifici), senza richiedere che il codice client conosca i tipi specifici di implementazione di questi servizi. Incapsula il processo di ottenimento del servizio necessario.

Vantaggi del Service Locator:

  • Accesso centralizzato: Facilita l’ottenimento di servizi da qualsiasi parte dell’applicazione.
  • Flessibilità: Permette di cambiare facilmente le implementazioni dei servizi senza modificare il codice client.

Svantaggi del Service Locator (la principale ragione delle critiche):

  • Dipendenze nascoste: Il codice client non dichiara esplicitamente le proprie dipendenze, il che rende difficile capire quali servizi sono necessari.
  • Testabilità: È difficile testare le classi che usano il Service Locator, poiché le dipendenze non possono essere facilmente sostituite (mocked).
  • Violazione del principio di inversione delle dipendenze (DIP): Invece di ottenere le dipendenze tramite il costruttore o proprietà, la classe le richiede attivamente.
  • Difficoltà nella gestione del ciclo di vita: Il Service Locator spesso non può gestire il ciclo di vita dei servizi registrati (ad esempio, creare singleton o oggetti transitori).

Esempio di implementazione semplice:

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($"Servizio di tipo {typeof(TService).Name} già registrato.");
        }
        _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($"Servizio di tipo {typeof(TService).Name} non trovato.");
    }
}

Esempio di utilizzo:

// Registrazione del servizio
ServiceLocator.RegisterService<ILogger>(new ConsoleLogger());

// Ottenimento del servizio
ILogger logger = ServiceLocator.GetService<ILogger>();
logger.LogInfo("Hello, Service Locator!");

Nel moderno sviluppo C#, il Service Locator viene spesso sostituito dall’uso di contenitori di Inversion of Control (IoC), che forniscono una Dependency Injection (DI) completa, considerata un’approccio più preferibile per la gestione delle dipendenze e per migliorare la testabilità del codice. I contenitori IoC permettono di dichiarare esplicitamente le dipendenze e di iniettarle automaticamente, seguendo i principi di DIP.