Inversion of Control e dintorni: Dependency Injection – parte 3 di 3

Nel post precente ho introdotto il pattern Dependency Injection, facente parte della famiglia di pattern IoC: qui discuterò, invece, del pattern Service Locator.

Proseguendo con l’esempio esposto nelle precedenti puntate il problema da risolvere è che la classe DirectoryController, presentata nei post precedenti, non rispetta il principio Dependency Inversion Principle. Infatti dipende pesantemente dalla classe utilizzata per il logging.

Abbiamo già dato una prima soluzione, ma in questa parte daremo una versione alternativa.

In questa caso invece di passare la classe da usare per il logging nel costruttore, o in un metodo o proprietà, (vedi Dependency Injection) ci si affida a uno “store centrale”, che memorizza tutte le associazioni interfaccia-istanza dell’oggetto da utilizzarsi.

Quindi usando questo store è possibile prelevare l’instanza della classe logger di interesse.

Più facile a vedersi con un esempio che a descrivere.

Per iniziare creiamo lo store centrale (locator).

Nulla di particolarmente strano: si tratta di uno store centrale che accoglie l’associazione tra l’interfaccia e la relativa implementazione.

Per realizzare la funzionalità usa un Dictionary che viene alimentato tramite il metodo Mappa, e consultato tramite GetService.

SimpleLocator.singletoneSimpleLocator.Mappa(ILogger,LogWriter);

Usando l’istruzione sopra si inserisce nel dictionary _map l’informazione ILogger – instanza della classe LogWriter.

Questa informazione sarà ovunque richiamabile (vedi utilizzo di static).

ILogger m_Logger = SimpleLocator.singletoneSimpleLocator.GetService()

Qui si avrà nell’oggetto m_Logger l’instanza della classe denunciata con il metodo Mappa.

Grazie a questa implementazione è possibile modificare la classe DirectoryController come nel seguito.

Ecco che per utilizzare il corretto oggetto logger viene interrogato il Locator che, precedente alimentato (tramite Mappa) resituirà l’istanza corretta su cui lavorare.

Richiamo nuovamente l’attenzione sul fatto che ovviamente prima di utilizzare la classe DirectoryController occorre richiamare prima il metodo mappa di SimpleLocator.

Anche usando questo pattern si è ottenuto di disaccoppiare la classe logger dalla classe DirectoryController.

Il SimpleLocator mostrato sopra è certamente funzionale e funzionante, però posso affermare che in progetti reali è assolutamente inutile.

In altri termini il codice qui mostrato deve essere considerato con un esempio didattico per capire le potenzialità del service locator.

Infatti non solo .Net Core ha integrato al suo interno una cosa simile (ServiceLocator) che è uno strumento molto più evoluto e articolato, ma nel caso per qualche motivo NON voleste usare questo strumenti è sempre consigliabile usare delle librerie ad hoc (ad esempio SimpleIOC, Ninject, ma anche altre) che forniscono le necessarie caratteristiche di perfomance e duttilità che l’implementazione esposta non dispone.

Spero che queste mie righe siano state utilili ! Buona lettura.