Giorni fa mi lamentavo della scarsità di documentazione
riguardante Community Server: ho dunque deciso di sopperire a questa mancanze
scrivendo dei post a riguardo. Probabilmente troverete alcune di queste cose
cercando sui forum di CS.org o sull'appena lanciato CSMVP.com
Ma siccome il programmatore italiano è pigro e non
legge la doc in inglese, cerco di provvedere inaugurando una serie di articoli
in Italiano su come estendere CommunityServer.
Ci sono diversi modi per personalizzare CommunityServer:
- Graficamente, creando temi e skin (sia generici, che per i blog, le photo
gallery ed i forum)
- aggiungendo nuove funzionalità (cioè creando nuovi applicativi per CS)
scrivendo degli AddOn: ad esempio stanno già facendo un
CSWiki
- modificando il comportamento delle operazioni standard dei blog, forum,
registrazione utente, scrivendo dei Moduli (CSModules)
- estendendo le informazioni salvate nella registrazione utente
- accedendo alle informazioni salvate in CS da applicazione esterne (ad
esempio un vostro portale che deve però autenticare gli utenti in base alle
informazioni presenti nel DB di CommunityServer)
Sviluppare un CSModule è il modo più veloce per entrare in
contatto con le API di CS, quindi inizio la mia serie di post partendo da come
si sviluppa un CSModule.
Installare CommunityServer
Ovviamente la prima operazione da fare è installare in locale
CommunityServer.
Per sviluppare è sufficiente avere l'installazione binaria, ma per chi volesse esiste
anche l'SDK, che include anche tutto il codice sorgente
della versione Express.
Se usate l'MSI del quale ho fornito il link, alla fine dell'installazione
avrete un'instanza di CS installata, con il DB già creato e popolato con dati
d'esempio, normalmente accessibili all'indirizzo http://localhost/cs (o similare)
Creare il progetto VS2005
Ora potete iniziare a sviluppare il vostro modulo per CS.
Per farlo è
sufficiente creare un "Class Library" project con VS2005, creare un folder nel
quale copiare le dll core di Community Server, e creare dei riferimenti alle
librerie necessarie. Ipotizzando di voler sviluppare un
CSModule che interagisce con il Forum saranno necessarie:
- CommunityServer.Components.dll
- CommunityServer.Discussions.dll
Nel caso voleste interagire con i blog, avreste dovuto creare un riferimento
alla dll CommunityServer.Blogs.dll. E
se volevo interagire con le Gallery? Beh... indovinate
Queste librerie contengono tutte le API e le entities necessarie per accedere
a tutte le informazioni necessarie per sviluppare dei moduli.
L'interfaccia ICSModule
Affinche una classe sia identificata come modulo di CommunityServer è
necessario che implementi l'interfaccia ICSModule.
L'unico metodo di questa
interfaccia è il metodo Init.
Ecco come si presenta lo scheletro di un CSModule.
using System;
using CommunityServer.Components;
using CommunityServer.Discussions.Components;
using CommunityServer.Blogs.Components;
namespace CSModuleTest
{
class CSModuleTest: ICSModule
{
#region ICSModule Members
public void Init(CSApplication csa, System.Xml.XmlNode node)
{
//Qui va l'implemenazione del metodo
}
#endregion
}
}
La domanda che sorge spontanea, e che mi sono fatto pure io appena ho visto
l'interfaccia è: ma dove sono i metodi che vengono chiamati ogni volta che CS
vuole far entrare in gioco i moduli?
Gli sviluppatori di CS hanno deciso che le interfacce sono troppo complesse
da gestire in un'applicativo OpenSource per via della impossibilità di fare
versioning. Quindi hanno deciso di usare l'approccio che MS ha usato per gli
HttpModule e HttpHandler: cioè usare gli eventi.
Quindi, nel metodo Init, ogni modulo deve "dichiarare" che eventi vuole
gestire, e poi implementare il codice per gestirle nell'appropriata funzione di
gestione dell'evento.
Un ottimo post sull'argomento (con conseguente discussione) è stato scritto
dal capo supremo di SubText, Phil Haack: Building Plugins Resilient To Versioning
Dall'articolo ne segue che il
framework per i plugin di SubText sarà event-driven
Ma torniamo al nostro CSModule:
quali sono gli eventi che vengono alzati
dalla CSApplication, e che possono essere gestiti da il
nostro modulo?
Ce ne sono una 20ina, e sono elencati sul Wiki degli sviluppatori.
Se intanto volete inziare
a guardarli, i nomi sono abbastanza auto-esplicativi.
Comunque li
approfondiremo in un'altro post, ma ora come esempio guardiamo l'evento alzato
ogni volta che viene salvato un post: PostPostUpdate.
Con Post si intende sia
una entry nel blog, sia un messaggio nel forum, sia un commento ad un blog,
ecc... (cioè tutti gli elementi che ereditano dalla classe Post).
Ecco come sarebbe il modulo di prima con aggiunto l'event handler dell'evento
PostPostUpdate:
using System;
using CommunityServer.Components;
using CommunityServer.Discussions.Components;
using CommunityServer.Blogs.Components;
namespace CSModuleTest
{
class CommunityCreditPointSubmission: ICSModule
{
#region ICSModule Members
public void Init(CSApplication csa, System.Xml.XmlNode node)
{
csa.PostPostUpdate += new CSPostEventHandler(csa_PostPostUpdate);
}
#endregion
void csa_PostPostUpdate(IContent content, CSPostEventArgs e)
{
if (e.ApplicationType == ApplicationType.Forum)
{
ForumPost post = (ForumPost) content;
System.Diagnostics.Debug.WriteLine("Post Title = " + post.Subject);
}
}
}
}
Ora che il nostro Modulo è pronto come la aggiungo al CommunityServer
installato il locale?
Basta aggiungere la seguente riga nel
communityserver.config
<add name = "MyCSModule" type = "CSModuleTest.CSModuleTest, CSModuleTest" />
E per debuggare?
Non potendo lanciare direttamente il server in debug (si potrebbe fare se
avessimo usato l'SDK, ma secondo me sbattimento inutile), si deve lanciare
l'applicazione nel browser, e poi attaccarsi al processo di ASP.NET col debugger
di VS2005.
La prossima puntata, vedremo la classa base di CommunityServer: CSContext