Inversion of Control e Dependecy Injection fatti in casa (2)

Nella precedente puntata eravamo rimasti alla descrizione del service layer di accesso alle funzionalità applicative. Inoltre, la definizione dell'interfaccia "IFinderProvider" permette di esporre il contratto condiviso tra i differenti plugin di ricerca: share, local e webservice.

Come detto, prima di passare alla descrizione del "container", responsabile della gestione modulare operata da Dependency Injection, vediamo l'implentazione reale del modulo "Local". Il codice riportato è una banalissima implementazione di "mockup" che emette dei sample data. In una situazione reale la logica applicativa eseguirebbe una ricerca sul disco locale, magari scansionando le directoy secondo una struttura definita, e partendo da un percorso "radice" definito da configurazione applicativa.

La cosa importante è che il modulo "Local" è implementato dalla classe "LocalFinderProvider", che rispetta i termini del contratto descritto da "IFinderProvider"; e questo è tutto quello che ci serve sapere per poterlo correttamente utilizzare nel meccanismo che stiamo progettando.

Con il medesimo spirito andiamo ad esaminare l'implementazione il modulo "Share" realizzato dalla classe "ShareFinderProvider": Ancora una volta i sample data mi aiutano ad evitare l'implementazione reale, abbozzata però in una caratteristica essenziale di questa implementazione: l'autenticazione. La classe "ActiveDirectoryAuthenticator" ci permetterà di impersonare una particolare utenza per l'accesso alla share di rete, attraverso il costrutto "using" e sfruttando l'interfaccia "IDisposable". All'interno dello scope di "using", infatti, l'autenticazione del processo in esecuzione avviene con un'utenza definita dalla tripla "username/password/dominio", che permette di identificare univocamente un utente di Active Directory, e impersonare le sue credenziali per l'intera valenza dello scope definito tra i "brachets" del costrutto "using" stesso. Chiudiamo la lista dei moduli con erogatore di documenti tramite "web service". Anche "WebServiceFinderProvider", naturalmente, deve implementare l'interfaccia "IFinderProvider"; ma questo non gli impedisce di possedere un'implementazione in grado di fare uso di un "web client" per eseguire l'invocazione del servizio web remoto che sarà responsabile di individuare e rendere disponibili i documenti presenti sull'host. Prima di chiudere, ritorniamo su un concetto introdotto nel primo post della serie. Si vuole permettere all'applicativo di essere tanto flessibile da poter aggiungere o togliere funzionalità senza ricompilare il codice sorgente, semplicemente modificando la configurazione del sistema stesso attraverso la manipolazione del "App.config". Per fare questo dobbiamo comunque avere a disposizione una classe che sia in grado di leggere la configurazione personalizzata del sistema, ed esporre i valori direttamente tramite opportune classi e proprietà liberamente accessibili.

Non scenderò nel dettaglio di come creare una configurazione personalizzata in .NET; per questo vi rimando ad un post un po' datato che scrissi lo scorso anno. Quindi vi proporro ancora una volta la semplicificazione di una struttura in grado di persistere la definizione delle configurazioni dei provider che abbiamo appena implementato. Ogni "item" di configurazione, identificato dalla classe "ProviderConfiguration" rappresenterà le informazioni minime che serviranno al nostro gestore di plugin per creare un'istanza del provider stesso senza conoscerne i dettagli implementativi. Nel prossimo ed ultimo capitolo della saga, finalmente vedremo l'implementazione di "FinderIoc" e le sue peculiarità. Quindi...restate sintonizzati...

M.

Commenti

Post popolari in questo blog

Cancellazione fisica vs cancellazione logica dei dati

Restore di un database SQL Server in un container Docker

Costruire una DataSession custom con Chakra.Core