• Voici le diagramme d'état de la "vie" d'un bug. Il pourrait être plus complexe ...
  • Pour chaque évenement, nous avons la possibilité de créer des diagrammes séquentiels qui réaliseront plusieurs activités.
  • Tout comme en WCF, il faut définir un "contrat" qui définit ce qui sera utilisé dans le workflow en "données externes.
  • [ExternalDataExchange]
    public interface IBugService
    {
        event EventHandler<ExternalDataEventArgs> BugCreated;
        event EventHandler<ExternalDataEventArgs> BugUpdated;
        event EventHandler<ExternalDataEventArgs> BugOpened;
        event EventHandler<ExternalDataEventArgs> BugEnded;
        event EventHandler<ExternalDataEventArgs> BugCanceled;
    }
    
  • Il faut implémenter une classe héritant de ce contrat qui gèrera les évenements auquel le workflow s'abonnera. Il est important de ne pas oublier que les types qui sont passés sont sérialisable. Le champ "instanceId" est également indispensable pour retrouver l'instance à laquelle on souhaite envoyer l'évenement.
  • [Serializable]
    public class BugService : IBugService
    {
        public void RaiseBugCreatedEvent(Guid instanceId)
        {
            if (BugCreated != null)
            {
                ExternalDataEventArgs e = new ExternalDataEventArgs(instanceId);
                e.WaitForIdle = true;
                BugCreated(this, e);
            }
        }
        public event EventHandler BugCreated;
    
    
        public void RaiseBugUpdatedEvent(Guid instanceId)
        {
            if (BugUpdated != null)
            {
                ExternalDataEventArgs e = new ExternalDataEventArgs(instanceId);
                e.WaitForIdle = true;
                BugUpdated(this, e);
            }
        }
        public event EventHandler BugUpdated;
    
    
        public void RaiseBugOpenedEvent(Guid instanceId)
        {
            if (BugOpened != null)
            {
                ExternalDataEventArgs e = new ExternalDataEventArgs(instanceId);
                e.WaitForIdle = true;
                BugOpened(this, e);
            }
        }
        public event EventHandler BugOpened;
    
    
        public void RaiseBugEndedEvent(Guid instanceId)
        {
            if (BugEnded != null)
            {
                ExternalDataEventArgs e = new ExternalDataEventArgs(instanceId);
                e.WaitForIdle = true;
                BugEnded(this, e);
            }
        }
        public event EventHandler BugEnded;
    
        public void RaiseBugCanceledEvent(Guid instanceId)
        {
            if (BugCanceled != null)
            {
                ExternalDataEventArgs e = new ExternalDataEventArgs(instanceId);
                e.WaitForIdle = true;
                BugCanceled(this, e);
            }
        }
        public event EventHandler BugCanceled;
    }
    
  • Instanciation du Workflow + lancement des évenements. En cas de saut dans les états, une exception se lancera indiquant qu'il n'a pas pu trouver de référence pour cette état pour l'instance de ce workflow.
  • WorkflowRuntime runtime = new WorkflowRuntime();
    
    ExternalDataExchangeService dataExchangeService = new ExternalDataExchangeService();
    runtime.AddService(dataExchangeService);
    
    BugService bugService = new BugService();
    dataExchangeService.AddService(bugService);
    
    runtime.StartRuntime();
    
    WorkflowInstance instance = runtime.CreateWorkflow(typeof(Workflow1));
    instance.Start();
    
    bugService.RaiseBugCreatedEvent(instance.InstanceId);
    bugService.RaiseBugUpdatedEvent(instance.InstanceId);
    bugService.RaiseBugOpenedEvent(instance.InstanceId);
    bugService.RaiseBugCanceledEvent(instance.InstanceId);
    Console.ReadKey();
    
  • Résultat à l'écran
  • Sources de l'exemple
  • Télécharger
Voici un mini exemple certes peu expliqué mais qui suffit normalement à la compréhension de WF pour la partie diagramme d'états. Je reviendrai prochainement poster ici des articles plus profond sur les activités de validation etc. Bonne soirée.