HandleExternalEvent & CallExternalMethod sous Workflow Foundation
Les Activity HandleExternalEvent & CallExternalMethod, sont tout deux indispensable dans le developpement de workflow. Ce sont en quelque sorte les entrées-sorties entre le workflow et le programme host.
Le HandleExternalEventActivity va pemettre de marquer une pause dans le deroulement d’un workflow en attendant le déclement d’un evenement. Le CallExternalMethodActivity va quand à lui effectuer en quelque sorte l’opération inverse, à savoir, déclencher l’appel d’une methode externe au workflow.
Les methodes et evenement vont devoir etre défini dans une interface marquée par l’attribut ExternalDataExchange. Le programme host, lui, devra ajouter le service ExternalDataExchangeService
Mission 1 : Création du projet DTO pour les objets communs
1) Créons donc un nouveau projet de type Class Library en VB.net. Nous allons commencer tout d’abord par ajouter une référence au Workflow Foundation qui est : System.Workflow.Activities
2) Ensuite créons une classe nommé MyEventArgs qui nous pemettra de passer des arguments dans notre evenement. Nous allons, dans cette classe, stocker un petit message, il faudra donc créer un champ et une propriété de type String nommé Message.
Cette classe doit être Serializable et doit hériter de la classe System.Workflow.Activities.ExternalDataEventArgs. Il faudra donc dans le code du constructeur ajouter un MyBase.New(instanceId) avec comme instanceId, l’instance de notre workflow en Guid pour que l’evenement puisse etre mappé sur la bonne instance de workflow.
Notre classe pourrait ressembler à cela :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <Serializable()> _ Public Class MyEventArgs Inherits System.Workflow.Activities.ExternalDataEventArgs Private m_Message As String Public Property Message() As String Get Return m_Message End Get Set(ByVal value As String) m_Message = value End Set End Property Sub New(ByVal instanceId As Guid, message as String) MyBase.New(instanceId) m_Message = message End Sub End Class |
3) Créons maintenant notre Interface de communication que l’on nommera dans notre exemple : ICommunication.
L’interface doit être marquée par l’attribut System.Workflow.Activities.ExternalDataExchange().
Nous allons définir une methode nomme MaMethode qui prendra en argument un message en string et un evenement nommé MonEvenement de type MyEventArgs créé juste avant :). Le code pourrait être :
1 2 3 4 5 | <System.Workflow.Activities.ExternalDataExchange()> _ Public Interface ICommunication Sub MaMethode(ByVal message As String) Event MonEvenement As EventHandler(Of MyEventArgs) End Interface |
4) Pour finir, compiler votre projet DTO et passons à la création du workflow
Mission 2 : Création du workflow
1) Commencons par créer un nouveau projet dans notre solution de type Sequential Workflow Library et ajouter la référence au projet DTO.
Notre workflow va ressembler à ca :
Au démarrage, il attend l’evenement MonEvenement (Activity HandleExternalEvent) qui contient un message via la classe MyEventArgs , puis quand l’evenement est recu, appel MaMethode (Activity CallExternalMethod) en passant en parametre le message contenu dans notre evenement.
Plutot qu’un long baratin, la démo en video :
Mission 3 : Création de la couche service
Il ne vous plus qu’a créer la couche service qui s’occupera de démarrer le runtime et les instances de votre workflow. C’est elle aussi qui implémentra l’interface ICommunication.
Ici, notre couche service sera tres simple. Elle disposera des methodes StartRuntime et StartInstance pour demarrer le runtime du WF et l’instance de notre workflow. La methode DeclencherEvent s’occupera de declencher l’evenement. De plus, elle implementra notre interface ICommunication (methode MaMethode et evenement MonEvenement). A noter que lors de la creation de notre runtime, nous avons ajouter le service ExternalDataExchangeService pour pouvoir communiquer avec notre workflow via notre Interface.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Public Class Service Implements DTO.ICommunication Dim runtime As Workflow.Runtime.WorkflowRuntime Dim instance As Workflow.Runtime.WorkflowInstance Sub StartRuntime() runtime = New Workflow.Runtime.WorkflowRuntime() Dim eds As New Workflow.Activities.ExternalDataExchangeService() runtime.AddService(eds) eds.AddService(Me) runtime.StartRuntime() End Sub Sub StartInstance() instance = runtime.CreateWorkflow(GetType(WorkflowDemo2.Workflow1)) instance.Start() Console.WriteLine("InstanceId {0} demarrée", instance.InstanceId.ToString()) End Sub Sub DeclencherEvent(ByVal message As String) RaiseEvent MonEvenement(Nothing, New DTO.MyEventArgs(instance.InstanceId, message)) End Sub Public Sub MaMethode(ByVal message As String) Implements DTO.ICommunication.MaMethode Console.WriteLine("MaMethode appelée. Le message est : {0}", message) End Sub Public Event MonEvenement(ByVal sender As Object, ByVal e As DTO.MyEventArgs) _ Implements DTO.ICommunication.MonEvenement End Class |
Mission 4 : Création de la GUI
Ici dans notre projet notre GUI sera en mode console. Elle doit juste faire reference à notre couche service et l’instancier. Le code peut être :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Module Module1 Sub Main() 'Instanciation de la couche service Dim service As New Service() ' Demarrage du Runtime WF service.StartRuntime() ' Demarrage d'une instance de notre Workflow service.StartInstance() ' Declenchement de l'evenement Console.Write("Message a passer dans l'evenement ? ") service.DeclencherEvent(Console.ReadLine()) ' Fin Console.Read() End Sub End Module |
Ce qui donne à l’ecran :
Conclusion
C’est certe un exemple très simple et qui ne sert a rien, mais j’espere avoir pu vous donner quelques tips pour l’utilisation des HandleExternalEvent & CallExternalMethod au sein d’un workflow sous Worfkflow Foundation.
**UPDATE** : les sources du projet ICI