Ricevere eventi esterni in WF con HandleExternalEventActivity

di Cristian Civera, in Windows Workflow Foundation,

Nella realizzazione di workflow è molto probabile che il flusso logico che si rappresenta abbia bisogno di interagire con l'esterno per ricevere input dall'utente o da altri sistemi informatici che partecipano al processo.

Per questo scopo Windows Workflow Foundation mette a disposizione la HandleExternalEventActivity che permette di interrompere l'elaborazione del flusso mettendolo in stato di attesa di un evento esterno.
In questo script si crea un semplice esempio di workflow di registrazione di un utente che necessita ad un certo punto di una conferma dall'esterno, mediante un'ipotetica pagina web o email di conferma.

Per poter notificare il workflow occorre definire un'interfaccia con almeno un evento che il workflow poi intercetterà:

[ExternalDataExchange()]
interface IRegistrationWorkflowEvent
{
    event EventHandler<RegistrationExternalDataEventArgs> RegistrationConfirmed;
}

L'evento in questione deve includere alcune informazioni base contenute nella classe ExternalDataEventArgs ed eventualmente delle proprie. In questo caso si prepara una classe con la proprietà IsConfirmed per conoscere l'esito o meno della conferma da parte dell'utente:

[Serializable()]
public class RegistrationExternalDataEventArgs : ExternalDataEventArgs
{
    public RegistrationExternalDataEventArgs(Guid instanceId)
        : base(instanceId)
    {}

    public bool IsConfirmed { get; set; }

}

Passando ora al workflow occorre inserire l'attività HandleExternalEventActivity specificando le proprietà InterfaceType su IRegistrationWorkflowEvent e EventName su RegistrationConfirmed. Eventualmente è possibile intercettare l'evento Invoked per eseguire del codice in caso di chiamata dall'esterno. Nel esempio corrente si stampa a video il risultato:

private void handleExternalEventActivity_Invoked(object sender, ExternalDataEventArgs e)
{
    Console.WriteLine("Confirmed: " + ((RegistrationExternalDataEventArgs)e).IsConfirmed);
}

L'interfaccia definita in precedenza va dunque implementata a seconda delle proprie esigenze e tecniche si vogliono utilizzare per ricevere l'input esterno. Una semplice implementazione può essere la seguente:

[Serializable()]
class RegistrationWorkflowEvent : IRegistrationWorkflowEvent
{

    public event EventHandler<RegistrationExternalDataEventArgs> RegistrationConfirmed;

    public void NotifyRegistration(Guid instanceId, bool confirmed)
    {
        OnRegistrationConfirmed(new RegistrationExternalDataEventArgs(instanceId) { IsConfirmed = confirmed });
    }

    protected virtual void OnRegistrationConfirmed(RegistrationExternalDataEventArgs args)
    {
        RegistrationConfirmed(this, args);
    }
}

Lo script precedente espone semplicemente un metodo pubblico per lanciare l'evento che il workflow sta intercettando.
Per ultimo occorre sfruttare il servizio ExternalDataExchangeService nel runtime di workflow così da avere un'istanza della classe che contiene l'evento e poter così lanciare l'evento quando necessario:

// Creo la classe contenente l'evento
RegistrationWorkflowEvent rwe = new RegistrationWorkflowEvent();

// Creo il servizio di gestione eventi esterni
ExternalDataExchangeService externalDataExchangeService = new ExternalDataExchangeService();
// Aggiungo al runtime
workflowRuntime.AddService(externalDataExchangeService);
// Aggiungo ai servizi di gestione eventi
externalDataExchangeService.AddService(rwe);

In qualsiasi momento è poi possibile notificare l'evento in base all'istanza del workflow (in teoria ogni registrazione è serviva da una istanza diversa):

rwe.NotifyRegistration(instance.InstanceId, true);

Tocca al programmatore mantenere l'instanceID del workflow (Guid), facendolo passare nella sessione dell'utente, o nel corpo dell'email ed inoltre occorre prestare attenzione al fatto che quando il workflow passa in stato di attesa, potrebbe essere scaricato o essere sottoposto a ricicli dell'host del runtime. Occorre quindi attivare i servizi di persistenza per poter recuperare l'istanza anche a distanza di giorni.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi