Continuo la serie di post che ha riscosso un 
inatteso successo tornando a parlare di Monad e dei suoi provider. Come promesso 
la precedente puntata ecco finalmente un po' di codice che spiega come 
implementare un provider che risponda ad un device fittizio che chiameremo sql:\ 
ottenendo il risultato di consentirci di navigare lo schema del database come se 
fosse un filesystem.
Per chiarire l'obbiettivo che ci poniamo 
innanzitutto proviamo a spiegare in che modo avverrà la navigazione all'interno 
di SqlServer. Se pensiamo ad un database server Sql, possiamo individuare una 
sorta di gerarchia riconducibile ad un path analogo a quello del filesystem. Al 
primo livello avremo il server, poi il database, poi ancora le tabelle ed infine 
i campi che compongono una singola tabella. La scelta in effetti è arbitraria in 
quanto è evidente che si sarebbe potuto scegliere un diverso modo di ordinare 
gli oggetti, ma allo scopo del post, quanto appena descritto è più che 
sufficiente.
Quindi scrivendo il seguente path dovremmo poter 
raggiungere i campi della tabella Employees nel database Northwind del server 
locale:
sql:\(local)\Northwind\Employees
Per ottenere questo risultato il primo passo da 
compiere è quello di creare una classe, che chiameremo SqlCmdletProvider che 
eredita da NavigationCmdletProvider. Questa classe dovrà inoltre essere decorata 
dall'attributo CmdletProviderAttibute oltre naturalmente a implementare l'unico 
metodo astratto di tale classe. Ecco un breve spezzone di codice:
using System;
using System.Management.Automation;
using System.Management.Automation.Provider;
[CmdletProvider("SqlCmdletProvider", ProviderCapabilities.None)]
public class SqlCmdletProvider : NavigationCmdletProvider
{
    protected override bool IsValidPath(string path)
    {
        return true;
    }
}
Dovremo naturalmente ricordarci di importare i namespace di Monad, 
e di referenziare i relativi assembly che troveremo nella directory di 
installazione. Ora il nostro provider compila, ma anche ammettendo di 
installarlo scopriremo che non è in grado di compiere alcuna azione. In 
particolare manca la possibilità di "agganciarsi" al drive fittizio sql: come 
richiesto dai requisiti che abbiamo espresso poco fa. E' qui che entrano in 
gioco la serie di metodi virtuali, esposti dalla classe 
NavigationCmdletProvider, facendo l'override dei quali si potranno iniziare ad 
ottenere i comportamenti richiesti. Per poter assegnare il drive sql: al nostro 
provider dovremo sovrascrivere il metodo InitializeDefaultDrives() il quale 
dovrà tornare una collection dei drive cui il nostro provider fa capo; Eccone 
l'implementazione:
protected override Collection<System.Management.Automation.DriveInfo> InitializeDefaultDrives()
{
    Collection<System.Management.Automation.DriveInfo> drives = 
               
new Collection<System.Management.Automation.DriveInfo();
    drives.Add(
        new System.Management.Automation.DriveInfo(
            "sql",
            this.ProviderInfo,
            "\\", 
            "Sql MSH Navigation Provider", 
            null));
    return (drives);
}
Come già detto questo metodo informerà il runtme di quali drive 
fanno capo al nostro provider. Una volta installato il provider potremmo 
assicurarci che esso risponda correttamente lanciando la cmdlet get-provider per 
ottenere quelo che segue:
MSH C:\> get-provider
Name                 Capabilities                                      Drives
----                 ------------                                      ------
SqlCmdletProvider    None                                              {sql}
Alias                ShouldProcess                                     {Alias}
Environment          ShouldProcess                                     {Env}
FileSystem           Filter, ShouldProcess                             {C, D, E, F, G}
Function             ShouldProcess                                     {Function}
Registry             ShouldProcess                                     {HKLM, HKCU}
Variable             ShouldProcess                                     {Variable}
Certificate          ShouldProcess                                     {cert}
Tra i provider installati è elencato anche il nostro e se proviamo 
a scrivere "cd sql:\" il nostro provider accetterà il percorso specificato così 
come qualunque altro dato che nel metodo IsValiPath() abbiamo ritornato 
semplicemente true.  
Ora, prima di chiudere il post e lasciarvi per la prossima puntata, è 
opportuno che spieghi come si fa ad installare il provider in Monad. In effetti 
questa è la parte se volete più oscura alla qualeho trovato una sola soluzione, 
ma sospetto che ve ne siano altre che mi sono bellamente sfuggite. Quello 
che ho fatto io è stato di compilare una nuova shell includendo l'assembly 
del mio provider ottenendo così un nuovo eseguibile compatto che supporta 
anche il mio provider; Ecco la linea di comando MSH che ho utilizzato 
per lo scopo: