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 »
- 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
- 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 »
- 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)
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.
- 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.
- 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)
- 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 :
- 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 :