Magazine

Un provider per implementare MovableType

Andrea Boschin

28/09/2006

L'articolo presenta l'implementazione della MovableType API adottata per il sito di XeDotNet realizzata per mezzo di un Provider facilmente riutilizzabile

0%100%
per esprimere un voto รจ necessario registrarsi al sito

ASP.NET, OOP

XeDotNet.MovableType.zip (555,00 Kb)

Il passaggio da ASP.NET 1.1 a 2.0 ha portato in auge un modello di sviluppo che consente di riutilizzare facilmente delle funzionalità senza preoccuparsi troppo di doverle riscrivere ex-novo ogni volta che se ne presenti la necessità. Mi riferisco al tanto decantato ProviderModel. In effetti un provider come quello di Membership, o uno degli altri a scelta, è una sorta di mattoncino che si può facilmente incastrare nelle proprie applicazioni, dimenticandosi di come esso implementa le proprie funzionalità. In questo modo si è liberi di potersi dedicare in modo molto più produttivo ad altre caratteristiche peculiari dell'applicazione.

Molto spesso l'uso  di un provider è una scelta che porta a ridurre drasticamente i tempi di sviluppo. Mi sono più volte chiesto il motivo per cui ad oggi gli unici provider degni di nota sono quelli presenti nativamente nel framework 2.0. Spero di poter essere smentito, ma non ho mai avuto occasione di trovare provider specifici di altri domini applicativi. Creare un provider è una attività molto semplice, supportata da un appositamente studiato che al suo interno contiene una serie di strumenti che semplificano di molto la sua realizzazione. Il vero problema in realtà non è di ordine pratico. La caratteristica peculiare che deve avere un dominio applicativo per poter essere convertito in provider è quella, non sempre di immediata realizzazione, di poter essere isolato da altri domini non direttamente necessari. Il problema quindi è soprattutto analitico, e probabilmente è per questo che il Provider Model attualmente non ha ancora preso piede.

Recentemente ho avuto l'occasione di implementare una interfaccia MovableType per il sito di XeDotNet, e mi sono reso conto che questo ambito si presta molto bene all'implementazione di un modello a provider. L'interfaccia MovableType in effetti è un dominio applicativo perfetto per la creazione di un provider perchè le sue funzionalità sono molte ben definite ed isolate. Inoltre, un MovableTypeProvider è un servizio che può essere riutilizzato più volte, per diverse piattaforme di blogging perciò è decisamente auspicabile la scelta di tale modello.

Il Pattern Provider

E' opportuno ora cercare di capire ora quali sono le componenti che costituiscono un provider pattern - il design pattern su cui è basato il ProviderModel - e su questa base poi passare ad analizzare le classi concrete da realizzare per creare un MovableTypeProvider. Le componenti principali di un Pattern Provider sono le seguenti

Abstract Provider: Si tratta di una classe- dichiarata astratta - che definisce quali sono i metodi e le proprietà che dovranno essere esposte da un provider. Questa classe in ASP.NET tipicamente deriva direttamente da ProviderBase, una classe che a sua volta raccoglie informazioni in merito.

Concrete provider: Si tratta della classe che estende il provider astrattato implementandone le sue funzionalità in riferimento ad uno specifico storage. Questa sarà l'unica classe che dovrà essere scritta per potersi collegare a diversi servizi.

Provider Facade: Si tratta di una classe statica, la cui funzione è di risparmiare il codice necessario ad istanziare il Provider concreto adatto tra quelli presenti nellla configurazione e di facilitate allo sviluppatore l'uso dei provider concreati in modo trasparente.

Quando avremmo la necessità di usare uno qualunque dei metodi esposti dal provider prescelto il nostro unico compito sarà quello di chiamare la versione statica esposta dalla facade. Questa si occuperà per conto nostro di attivare il provider concreto e di chiamare il metodo corrispondente per mezzo del provider astratto sfruttando il polimorfismo.

Implementare il Provider

Il pattern provider così descritto è implementato pari pari da uno qualunque dei Provider disponibili nel framework, sia esso il MembershipProvider o il RoleProvider. Il MovableTypeProvider oggetto di questo articolo non fa alcuna differenza. Esso è costituito da tre classi, ognuna delle quali corrisponde ad un componente del pattern: MovebleTypeProvider è Provider astratto, MovableType è la classe facade. La versione concreta del provider, nel codice di esempio è il SampleMovableTypeProvider, ma questa classe in realtà è l'unica che dovremmo implementare per fare in modo che l'interfaccia MovableType si agganci al nostro repository di dati. Vediamo ora in dettaglio il codice partendo dalla classe facade. In particolare vedremo il metodo Initialize che è il cuore del suo funzionamento:

 

/// <summary>
/// 
Initializes this instance.
/// </summary>
private static void Initialize()
{
    
if (MovableType.initialized)
    {
        
if (MovableType.initializationException != null)
            
throw MovableType.initializationException;
    }
    
else
    
{
        
if (MovableType.initializationException != null)
            
throw MovableType.initializationException;

        
lock (MovableType.lockObj)
        {
            
if (MovableType.initialized)
            {
                
if (MovableType.initializationException != null)
                    
throw MovableType.initializationException;
            }
            
else
            
{
                
try
                
{
                    MovableTypeSettings settings = MovableTypeSettings.Current;
                    
if (settings.DefaultProvider == null ||
                        settings.Providers == 
null ||
                        settings.Providers.Count < 1)
                        
throw new ProviderException(Resource.GetString("You must provide a valid defaultProvider for this feature"));

                    MovableType.providers = 
new MovableTypeProviderCollection();
                    ProvidersHelper.InstantiateProviders(settings.Providers, MovableType.providers, 
typeof(MovableTypeProvider));
                    MovableType.provider = MovableType.providers[settings.DefaultProvider];
                    
if (MovableType.provider == null)
                        
throw new ConfigurationErrorsException(Resource.GetString("You must provide a valid defaultProvider for this feature"));
                    MovableType.providers.SetReadOnly();

                    
// read initialization here
                
}
                
catch (Exception ex)
                {
                    MovableType.initializationException = ex;
                    
throw;
                }

                MovableType.initialized = 
true;
            }
        }
    }
}


Quello che si nota immediatamente è che la classe adotta una strategia di lock per evitare concorrenza nella parte di inizializzazione. Infatti questa porzione di codice è critica poichè essa si incarica di creare le istanze Singleton dei provider dichiarati in configurazione. Scorrendo il flusso del codice si vede infatti che la classe preleva per mezzo della classe MovableTypeSettings i nomi dei tipi da istanziare e dopo aver provveduto a crearne l'istanza e inizializzarli li pone in una collection che rimane tale fino a che l'AppDomain non venga scaricato. In questa porzione di codice si nota anche l'utilizzo di una classe che fa parte del framework .NET che supporta la creazione di Providers; in particolare mi riferisco a ProvidersHelper che offre dei metodi utili ad istanziare i tipi.

La semplicità della creazione di un provider è tale che in realtà quella che ho appena illustrato è la parte più complessa del Provider Model. Come si può immaginare infatti, le restanti classi contengono una la dichiarazione dei metodi e l'altra la loro implementazione. L'unica cosa ulteriormente degna di nota è la gestione dei parametri di configurazione peculiari di ognuno dei providers. Per mezzo della classe ProviderBase che sta alla base della classe astratta, ognuno dei provider espone un metodo Initialize(). Questo metodo viene chiamato al momento dell'istanziazione da parte della classe ProvidersHelper e ad esso viene passata una NameValueCollection contenente i parametri immessi come attributi nell'xml del file di configurazione.

Nel codice allega è presente una implementazione completa del Provider Model per il MovableTypeProvider e una classe mock che dimostra come si possa creare facilmente un Provider. una volta avviato il progetto, che installa nell'IIS locale una virtual directory ~/services puntando Windows Live Writer o una qualunque applicazione che supporta MovableType all'indirizzo http://localhost/services/movabletype.asxp si sarà in grado di verificare il funzionamento del provider. Nel progetto è incluso anche un HttpHandler che intercetta le chiamate XmlRpc, per mezzo della libreria opensource CookComputing.XmlRpcV2 e le mappa sui metodi del provider.

Conclusione

A conclusione dell'articolo occorre rilevare due cose. Innanzitutto la facilità con cui, sfruttando le classi del framework si possa mettere in piedi un struttura fortemente riutilizzabile. Certo occorre studiare bene quali e quanti metodi esporre, ma una volta conclusa la fase analitica e implementato il provider la produttività ne trarrà sicuramente vantaggio. In secondo luogo va precisato che il codice presentato fa parte dell'implementazione dei servizi MovableType esposti dal sito web di XeDotNet realizzati per migliorare la gestione dei contenuti del sito. La speranza è che altre community di programmatori .NET possano trarne vantaggio. L'unica cosa che chiediamo è un link a questo articolo per fare in modo che esso possa avere la massima diffusione possibile.

Commenti
Nome

Sito web
Commento


indietro