Il concetto degli event receiver dovrebbe essere ormai famigliare a tutti gli sviluppatori SharePoint, dato che ne potevamo sfruttare le potenzialità già da SharePoint Portal Server 2003/WSS 2.
In linea di massima, scrivere un event receiver non è mai stato difficile. C'è sempre stata una classe da cui ereditare, e uno o più metodi da sovrascrivere e di cui pensare l'implementazione.
La rottura di scatole (permettetemi il termine) è sempre stata invece l'associazione del nostro event receiver custom a liste o document library.

Se non mi credete, torniamo un pò indietro nella storia..

Windows SharePoint Services 2.0 / SharePoint Portal Server 2003
Per legare del codice custom a qualche evento di una document library (e SOLO di una document library, perchè sulle liste non erano ancora stati implementati), si doveva modificare dei settings all'interno delle pagine di amministrazione di SharePoint e in quelle di configurazione della document library, sperando di non sbagliare il nome completo dell'assembly che conteneva il nostro receiver e il nome completo del tipo.
Ecco qua la documentazione che lo dimostra: http://technet.microsoft.com/en-us/library/cc288968(office.12).aspx
Lo so.. erano bei tempi :)

Windows SharePoint Service 3.0 / MOSS 2007
Ora possiamo avere receiver anche su liste, abbiamo molte operazioni in più da poter gestire e due diverse tipologie di associazione del receiver alla relativa lista o document library:
- associazione tramite una feature
- associazione tramite il modello ad oggetti di SharePoint
Al tempo, erano stati dei grandissimi passi avanti!
La rottura di scatole però era che non avevamo template per farci generare il codice di associazione e, per legare velocemente un receiver custom ad una lista, finivamo puntualmente per scrivere l'ennesima console application da dover lanciare a mano sulla macchina SharePoint. Questo fino a che non sono stati rilasciati su codeplex alcuni tool fantastici come SharePoint Event Handler Manger, SharePoint Event Handler Management Extensions for STSADM e SharePoint Events Manager.
Per chi ha ancora a che fare con SharePoint 2007, potete fare riferiemento a questo mio articolo:
- http://www.peppedotnet.it/Articoli/Wss3EventHandlers.aspx
e a queste pagine della documentazione Microsoft:
- http://msdn.microsoft.com/en-us/magazine/cc163318.aspx
- http://msdn.microsoft.com/en-us/library/ms463479.aspx
- http://msdn.microsoft.com/en-us/library/ms475328(v=office.12).aspx

SharePoint 2010
Eccoci al presente.. oggi possiamo legare del codice custom a siti, site collection, liste, elementi, documenti, content type, feature e workflow. Spero proprio che possa bastarvi :)
I metodi di associazione che avevamo disponibili in SharePoint 2007 sono tutti mantenuti.
Abbiamo un template specifico per la creazione di un event receiver da Visual Studio 2010.
E, grazie all'integrazione con PowerShell, possiamo registrare al volo event receiver su oggetti all'interno di SharePoint senza dover scrivere feature o console application. Il che, almeno dal mio punto di vista, è fantastico perchè ho a disposizione una vera e propria console di scripting che nel mio caso uso per aggiungere, togliere, modificare le associazioni dei miei event receiver, ma che posso utilizzare per fare qualsiasi cosa io desidiri sui miei siti SharePoint, senza dover compilare nessun progetto o scrivere codice XML di provisioning.

Ecco qundi che volendo aggiungere un nuovo event receiver su una lista SharePoint, mi basta aprire PowerShell dal menu dei programmi sotto la voce "Microsoft SharePoint 2010 Products" e scrivere questo script:

$web = Get-SPWeb -Identity http://servername 

$list = $web.Lists["Your list name"] 

$event = $list.EventReceivers.Add()
$event.Assembly = "Your full assembly name, Version=1.0.0.0, Culture=neutral, PublicKeyToken=..."
$event.Class = "Your class name"
$event.Name = "Test event from PowerShell"
$spEventReceiver.Type = 10002
$spEventReceiver.SequenceNumber = 1000
$spEventReceiver.Synchronization = 1
$spEventReceiver.Update()

Le propietà che vengono settate in questo script PowerShell non sono altro che le proprietà delle classi SPList e SPEventReceiver con cui siete stati abituati a lavorare fin'ora.
Le uniche due cose su cui bisogna porre attenzione sono le proprietà Type e Synchronization, in quanto essendo delle enum devono essere valorizzate con gli interi che corrispondono al valore di enumarazione che vogliamo utilizzare.
Per la proprietà Synchronization, abbiamo a disposizione i seguenti valori:
  • 1: Synchronous
  • 2: Asynchronous

Per la proprietà type invece, la lista è un pò più lunga:
  • -1: InvalidReceiver
  • 1: ItemAdding
  • 2: ItemUpdating
  • 3: ItemDeleting
  • 4: ItemCheckingIn
  • 5: ItemCheckingOut
  • 6: ItemUncheckingOut
  • 7: ItemAttachmentAdding
  • 8: ItemAttachmentDeleting
  • 9: ItemFileMoving
  • 101: FieldAdding
  • 102: FieldUpdating
  • 103: FieldDeleting
  • 104: ListAdding
  • 105: ListDeleting
  • 201: SiteDeleting
  • 202: WebDeleting
  • 203: WebMoving
  • 204: WebAdding
  • 501: WorkflowStarting
  • 10001: ItemAdded
  • 10002: ItemUpdated
  • 10003: ItemDeleted
  • 10004: ItemCheckedIn
  • 10005: ItemCheckedOut
  • 10006: ItemUncheckedOut
  • 10007: ItemAttachmentAdded
  • 10008: ItemAttachmentDeleted
  • 10009: ItemFileMoved
  • 10010: ItemFileConverted
  • 10101: FieldAdded
  • 10102: FieldUpdated
  • 10103: FieldDeleted
  • 10104: ListAdded
  • 10105: ListDeleted
  • 10201: SiteDeleted
  • 10202: WebDeleted
  • 10203: WebMoved
  • 10204: WebProvisioned
  • 10501: WorkflowStarted
  • 10502: WorkflowPostponed
  • 10503: WorkflowCompleted
  • 20000: EmailReceived
  • 32766: ContextEvent

Bene. Ora che abbiamo inserito un nuovo event receiver, vediamo quali altri script PowerShell possiamo utilizzare per facilitarci il lavoro.

Vogliamo vedere la lista di receiver che sono collegati ad una lista/document library? Ecco qua:

$web = Get-SPWeb -Identity http://servername 

$list = $web.Lists["Your list name"] 

$list.EventReceivers | Select Name,Assembly,Type


Vogliamo cancellare o modificare l’associazione di un event receiver? Ecco qua:

$web = Get-SPWeb -Identity http://servername 

$list = $web.Lists["My List Name"] 

$eventsCount = $spList.EventReceivers.Count
$class = "Your class name"
$type = 10002
for ($i = 0; $i -lt $eventsCount; $i+=1)
{
if ($list.EventReceivers[$i].Class -eq $class -and $list.EventReceivers[$i].Type -eq $type)
{
$list.EventReceivers[$i].Delete()
}
}
$list.Update()

Bello, no? :)

Purtroppo (e qui ho l'unica nota dolente del post) attualmente PowerShell non è funzionante se utilizzato per modificare contenuti SharePoint Online all'interno del pacchetto Office 365.
Resta di fatto che, per lo sviluppo e per la gestione delle nostre installazioni on premises, è uno strumento fondamentale che ogni sviluppatore SharePoint dovrebbe sapere utilizzare senza problemi.
Chissà poi, cosa ci riserverà il futuro :)