Workflow Foundation - Tutoriel 3.1 : Organigramme d’appel d’offres–Partie 2

Ceci est la suite du tutoriel 3.1 dont la première partie est accessible ici. Il s’agit de créer un workflow de gestion d’appels d’offre.

Etape 4 : Création de la première partie l’organigramme

L’objectif de cette étape est de construire la première partie de l’organigramme qui demande à saisir les informations de l’appel d’offre. Le but est aussi de manipuler les signets et l’activité « Pick ».

  • Ouvrez le workflow « AppelOffre.xaml »
  • Faites glisser un organigramme (FlowChart) sur le diagramme
  • Remarquez l’activité « Start »
  • Sur l’organigramme, créez une variable « appelData » de type « AppelOffreData », àa servira à stocker les informations sur l’appel d’offre
  • Créez une deuxième variable appelée « montantOffre » de type « Decimal » qui servira à stocker l’offre du soumissionnaire.
  • Ajoutez un argument en sortie appelé « acceptation » de type « Boolean ». Cet argument définira si l’offre a été acceptée ou rejetée.
  • Faites glisser une activité Assign sur l’organigramme. Dans cette activité, affectez à la variable « acceptation » la valeur « false ».
  • Remarquez un message d’erreur qui apparaît, ceci est dû que l’activité « Assign » n’est connectée à aucune autre activité.
  • Faites bouger la souris au dessus de l’activité « Start », remarquez des bords bleus qui apparaissent
  • Faites glisser un bord vers la nouvelle activité « Assign » pour que le message d’erreur disparaisse
  • Faites glisser une activité Pick sur l’organigramme
  • Connectez les activités « Assign » et « Pick »

image

 

  • Doublez-cliquez sur l’activité « Pick », remarquez une zone d’action et une zone de déclencheur et que l’activité a deux branches.
  • Avec le bouton droit de la souris, cliquez sur la deuxième branche puis supprimez-la
image
  • A partir de la boîte à outils, faites glisser une activité « AttendreReponse<T> »
  • Lorsqu’on demande le type de l’activité, choisissez « AppelOffreData »
  • Dans la propriété « Destinataire » de l’activité, entrez « Emetteur Appel Offre »
  • Dans la propriété « NomSignet », entrez « EntrerAppelData »
  • Dans la propriété « Result », entrez la variable « appelData »

 

image

  • Glissez une activité « WriteLine » dans la zone « Action » de l’activité « Pick »
  • Dans la propriété « Text » de l’activité, entrez l’expression suivante :
string.Format("Un appel de catégorie {0} et de budget {1} a été entré", appelData.Categorie, appelData.Budget)

image

 

Etape 5 : Exécution du workflow et gestion du signet

L’objectif de cette étape est de découvrir un autre mécanisme d’exécution des workflows basés sur la classe « WorkflowApplication ». Ce mécanisme nous permettra de gérer des évènements tels que l’entrée en mode «Idle » du workflow mais aussi de communiquer avec le workflow en déclenchant des signets.

  • A partir de l’explorateur de solutions, ouvrez le fichier « Program.cs »
  • Déclarez trois variables statiques privées appelées « _app » , « _etape » et « _random » de type « WorflowApplication » , « String » et « Random » respectueusement. Le but de la variable « _app » est d’exécuter et de gérer le workflow tandis que la variable « _etape » indique l’étape en cours et est gérée par l’interface.
private static WorkflowApplication _app;
private static string _etape = null;
private static Random _random = new Random();
  • Ajoutez une méthode statique appelée “ExecuterAppelOffre » qui n’a aucun paramètre.
  • Le code de cette méthode est comme ceci :
private static void ExecuterAppelOffre()
        {
            var aoActivity = new AppelOffre();
            _app = new WorkflowApplication(aoActivity);
            _app.Idle = new Action<WorkflowApplicationIdleEventArgs>(WorkflowVeille);
            _app.Completed = new Action<WorkflowApplicationCompletedEventArgs>(WorkflowTermine);
            _app.Run();
            AfficherInterface();
        }
  • La première instruction instancie le workflow a exécuter
var aoActivity = new AppelOffre();
  • La deuxième instruction crée une application qui va exécuter le workflow. A noter qu’on n’utilise plus « WorkflowInvoker ».
_app = new WorkflowApplication(aoActivity);
  • Les deux instructions suivantes affectent des évènements à l’application lorsque le workflow entre en mode « idle » ou bien si le workflow se termine.
_app.Idle = new Action<WorkflowApplicationIdleEventArgs>(WorkflowVeille);
_app.Completed = new Action<WorkflowApplicationCompletedEventArgs>(WorkflowTermine);
  • L’instruction suivante exécute le workflow.
_app.Run();
  • La dernière instruction affiche l’interface. A noter que l’instruction précédente « Run » ne bloque pas cette instruction car elle est exécutée dans un processus séparé. En d’autres mots, « Run » et « AfficherInterface » s’exécuteront en parallèle.
AfficherInterface();
  • Le code de la méthode WorkflowVeille est le suivant :
private static void WorkflowVeille(WorkflowApplicationIdleEventArgs args)
      {
          Console.WriteLine("le workflow est en mode veille");
          foreach (var signet in args.Bookmarks)
              switch (signet.BookmarkName)
              {
                  case "EntrerAppelData":
                      _etape = "EntrerAppelData";
                      break;
              }
      }
  • Le seul objectif de la méthode « Veille » est de déterminer à partir des signets créés du workflow est d’indiquer à partir de ces signets dans quelle étape nous sommes.
  • Le code de la méthode WorkflowTermine est comme ceci :
private static void WorkflowTermine(WorkflowApplicationCompletedEventArgs args)
      {
          _etape = "arret";
          var acceptation = (bool)args.Outputs["acceptation"];
          if (acceptation)
              Console.WriteLine("l'offre a été acceptée");
          else
              Console.WriteLine("l'offre a été rejetée");            
      }
  • Cette méthode indique que la dernière étape a été franchie. Elle récupère aussi la valeur de l’argument « acceptation » à partir des arguments en sortie (Outputs).
  • Le code de la méthode « AfficherInterface » est comme ceci :
private static void AfficherInterface()
        {
            bool arret = false;
            while (!arret)
            {
                switch (_etape)
                {
                    case "EntrerAppelData":
                        var data = GetOffreData();
                        _app.ResumeBookmark("EntrerAppelData", data);
                        break;
                    case "arret":
                        arret = true;
                        break;
                }
                Thread.Sleep(1000);
            }
        }
  • Cette méthode boucle indéfiniment jusqu’à ce que l’étape « arrêt » soit atteinte. A chaque boucle elle pause le processus pendant une seconde pour ne pas surcharge le processeur. Quand elle atteint l’étape « EntrerAppelData », elle demande à l’émetteur de saisir son offre.
  • Changez la méthode « Main » de façon à ce qu’elle appel la méthode « ExecuterAppelOffre »
static void Main(string[] args)
        {
            ExecuterAppelOffre();
            Console.ReadKey();
        }
  • Exécutez l’application pour voir le résultat

Etape 6 : Saisie de l’offre

L’objectif de cette étape est de demande au soumissionnaire de saisir son offre qui est représentée par un montant. Ici aussi, nous utiliserons une activité « Pick »

  • Faites glisser une activité « Pick » sur l’organigramme
  • Connectez les deux activités « Pick »
  • Doublez-cliquez sur le nouveau « Pick »
  • Supprimez la deuxième branche
  • Faites glisser une activité « AttendreReponse » sur la zone déclencheur du « Pick »
  • Pour le type de l’activité, choisissez « Decimal »
  • Dans la propriété « Destinataire » , entrez « Soumissionnaire »
  • Dans la propriété « NomSignet », entrez « PostulerOffre »
  • Affectez « montantOffre » à la variable « Result »
  • Glissez une activité « WriteLine » dans la zone « Action » du « Pick »
  • Dans la propriété « Text » entrez l’expression suivante :
string.Format("le soumissionnaire a entré une offre de {0}",montantOffre)

 

image

  • Revenez à l’organigramme parent
  • Après le deuxième Pick, ajoutez et connectez une activité « FlowSwitch » de type générique « String »
  • Ajoutez trois organigrammes (flowcharts) en dessous du « FlowSwitch »
  • Entrez les valeurs « OrgConsultation », « OrgNormal » et « OrgMéga » à la propriété « DisplayName » des trois organigrammes.
  • Connectez l’activité « FlowSwitch » avec les trois organigrammes.
  • Pour l’expression du « FlowSwitch », entrez « appelData.Categorie »
  • Pour la propriété du premier connecteur du switch, entrez « Consultation » pour la propriété « Case » et désactivez « IsDefaultCase »
  • Pour la propriété du deuxième connecteur du switch, entrez « Normal » pour la propriété « Case » et désactivez « IsDefaultCase »
  • Pour la propriété du troisième connecteur du switch, entrez « Méga » pour la propriété « Case » et désactivez « IsDefaultCase »
  • L’organigramme global devrait être comme celui-ci :

image

  • Ouvrez le fichier « Program.cs »
  • Changez les méthodes « AfficherInterface » et « WorkflowVeille » comme suit :
private static void WorkflowVeille(WorkflowApplicationIdleEventArgs args)
      {
          Console.WriteLine("le workflow est en mode veille");
          foreach (var signet in args.Bookmarks)
              switch (signet.BookmarkName)
              {
                  case "EntrerAppelData":
                      _etape = "EntrerAppelData";
                      break;
                  case "PostulerOffre" :
                      _etape = "PostulerOffre";
                      break;
              }
      }
 
private static void AfficherInterface()
      {
          bool arret = false;
          while (!arret)
          {
              switch (_etape)
              {
                  case "EntrerAppelData":
                      var data = GetOffreData();
                      _app.ResumeBookmark("EntrerAppelData", data);
                      break;
                  case "PostulerOffre":
                      var montant = LireDecimal("Votre offre :");
                      _app.ResumeBookmark("PostulerOffre", montant);
                      break;
                  case "arret":
                      arret = true;
                      break;
              }
              Thread.Sleep(1000);
          }
      }
  • Exécutez pour voir la progression du workflow

Autres parties :

Add comment

Loading