Amine Mostefai's Blog

Architecture is my passion :)

Amine

Hi and welcome to my blog. I share in this space a lot of posts related to software architecture, and software development. Content is mainly related to .NET CORE development, Angular, Sharepoint, Azure and Office 365. I hope that my articles are helpful and that you enjoy using them 😉

Tutoriel 1.1 : Découverte de Workflow Foundation 4.5

L’objectif de ce tutoriel, relatif au premier cours, est de dĂ©couvrir la structure d’une application WF 4.5 et les diffĂ©rentes façons de crĂ©er un workflow pour ensuite, l’exĂ©cuter.

Etape 1 – Ouverture de la solution et son exĂ©cution

L’objectif de cette Ă©tape est d’ ouvrir la solution de dĂ©monstration de ce module.

  • Lancer VS 2012
  • Choisir Fichier -> Ouvrir -> Projet Solution
  • Naviguez jusqu’au rĂ©pertoire de dĂ©monstrations
  • Ouvrez la solution « Demo1.sln », il s’agit d’une application console
  • En utilisant l’explorateur de solutions, ouvrez le fichier « Program.cs »
  • Le listing de ce fichier devrait ĂȘtre comme ceci :
class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("Workflows séquentiels");
            Console.WriteLine("--------------------------------------");
            var w1 = new TransactionBancaireWorkflow();
            w1.Montant = 55000;
            IDictionary<string, object> result = WorkflowInvoker.Invoke(w1);
            Console.WriteLine("Commission : {0}", result["Commission"]);
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("Diagrammes de flux");
            Console.WriteLine("--------------------------------------");
            var w2 = new TransactionBancaireDFWorkflow();
            w2.Montant = 9000;
            result = WorkflowInvoker.Invoke(w2);
            Console.WriteLine("Commission : {0}", result["Commission"]);
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("Diagrammes de machine d'Ă©tats");
            Console.WriteLine("--------------------------------------");
           
            var w3 = new TransactionValidationWorkflow();
            w3.Montant = 59000;
            var app = new WorkflowApplication(w3);
            app.Run();
            Console.WriteLine("appuyez sur une touche pour valider le workflow");
            Console.ReadKey();
            app.ResumeBookmark("signet", null);
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("Workflow créé par code");
            Console.WriteLine("--------------------------------------");
            var w4 = GetCodeWorkflow();
            WorkflowInvoker.Invoke(w4);
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("Workflow chargé à partir d'un fichier XML");
            Console.WriteLine("--------------------------------------");
 
            var w5 = ActivityXamlServices.Load("wf5.xaml");
            WorkflowInvoker.Invoke(w5);
            Console.ReadKey();
        }
 
        private static Activity GetCodeWorkflow()
        {
            var workflow = new Sequence()
            {
            };
            workflow.Activities.Add(new WriteLine()
            {
                Text = "Un workflow créé par code !"
            });
            return workflow;
        }
    }
  • ExĂ©cutez l’application en appuyant sur F5
  • Lorsqu’un message demandant d’appuyer sur une touche apparaĂźt, appuyez sur n’importe quelle touche

image

Etape 2 – AccĂšs Ă  un workflow sĂ©quentiel

L’objectif de cette Ă©tape est de voir la structure et de comprendre l’exĂ©cution d’un workflow sĂ©quentiel.

  • A partir de l’explorateur de solutions, ouvrez le fichier « TransactionBancaireWorkflow.xaml »
  • Remarquez le workflow chargĂ© dans le designer graphique

image

  • Remarquez que le workflow est dĂ©composĂ© d’une instruction conditionnelle (if) composĂ©e Ă  son tour de deux branches « if » et « else »
  • La premiĂšre branche calcule la commission Ă  partir du montant (0.2%) si le montant dĂ©passe 50000. Ensuite elle affiche le message indiquant que l’opĂ©ration a besoin de validation.
  • La deuxiĂšme branche affecte une valeur de zĂ©ro Ă  la variable commission.
  • En dessous de la fenĂȘtre du designer, cliquez sur le lien « Arguments »

image

  • Remarquez la prĂ©sence de deux arguments, l’un appelĂ© « Montant » et l’autre « Commission ». Les deux arguments sont de type « Decimal »
  • Remarquez que l’argument « Montant » est en entrĂ©e et que l’argument « Commission » est en sortie.
  • Revenez au fichier « Program.cs », examinez comment un workflow a Ă©tĂ© instanciĂ© :
var w1 = new TransactionBancaireWorkflow() ;
  • Les workflows sont crĂ©Ă©s comme n’importe quel object C#, en utilisant l’opĂ©rateur « new »
  • L’instruction suivante montre comment un environnement externe (le programme) fournit les valeurs des arguments en entrĂ©e du workflow (Montant). Il s’agit d’une simple affectation car un alias de propriĂ©tĂ© est crĂ©Ă© pour « Montant ».
w1.Montant = 55000 ;
  • L’instruction suivante exĂ©cute le workflow. Une nouveautĂ© de WF 4.5 est que c’est devenu trĂšs simple d’exĂ©cuter un workflow, juste en utilisant la classe « WorkflowInvoker » et la mĂ©thode « Invoke ».
  • Remarquez que la mĂ©thode « Invoke » renvoir un dictionnaire d’objets. Il s’agit des arguments en sortie crĂ©Ă©s par le workflow.
IDictionary<string, object> result = WorkflowInvoker.Invoke(w1);
  • Pour accĂ©der ensuite Ă  la valeur de commission, nous utiliserons la variable “result”
Console.WriteLine("Commission : {0}", result["Commission"]);
  • Changez le workflow en changeant le montant maximum (50000) dans le designer et/ ou en changeant l’argument « Montant » fourni dans « Program.cs Ă  Main »

Etape 3 : AccĂšs Ă  un workflow diagramme de flux

L’objectif de cette Ă©tape est de dĂ©couvrir un autre type de workflows : les diagrammes de flux

  • En utilisant l’explorateur de solution, ouvrez le fichier « TransactionBancaireDFWorkflow.xaml »
  • Remarquez que le workflow est graphiquement diffĂ©rent du workflow prĂ©cĂ©dent mais fonctionnellement Ă©quivalent

image

  • Remarquez que ce workflo a les mĂȘmes arguments que le workflow prĂ©cĂ©dent.
  • De la mĂȘme façon, l’argument « Montant » est fourni en utilisant une affectation et le workflow est exĂ©cutĂ© en utilisant « WorkflowInvoker »
var w2 = new TransactionBancaireDFWorkflow();
w2.Montant = 9000;
result = WorkflowInvoker.Invoke(w2);
Console.WriteLine("Commission : {0}", result["Commission"]);
  • Changez le montant en entrĂ©e et / ou le plafond de validation dans le workflow puis rĂ©Ă©exĂ©utez le programme

Etape 4 : AccĂšs Ă  un workflow d’états

L’objectif de cette Ă©tape est de dĂ©couvrir les workflows de machine d’état qui permettant de transiter un workflow d’un Ă©tat Ă  un autre jusqu’à atteindre un Ă©tat final. L’objectif est d’utiliser aussi certaines fonctionnalitĂ©s du designer.
  • En utilisant l’explorateur de solutions, ouvrez « TransactionValidationWorkflow.xaml »
  • Remarquez que le workflow est graphiquement diffĂ©rent des deux premiers

image

  • Remarquez que le workflow dĂ©marre par un Ă©tat initial
  • A partir de l’état initial, la transition « T1 » met le workflow dans un Ă©tat « AttenteVal » tandis que la transition « T2 » le met dans un Ă©tat final
  • Cliquez sur la transition « T1 » puis sur la fenĂȘtre de propriĂ©tĂ©s

image

  • Remarquez que la transition « T1 » a pour condition que le montant soit supĂ©rieur Ă  50000
  • De la mĂȘme façon, consultez la condition de la transition « T2 »
  • Affichez les arguments du workflows
  • VĂ©rifiez que le workflow possĂšde un argument en entrĂ©e « Montant » de type « Decimal »
  • Dans le workflow, doublez-cliquez sur l’état « AttenteVal »
  • Dans la zone de texte « Zoom » en dessous, entrez « 70% »

image

  • Remettez le zoom Ă  « 100% »
  • Remarquez que le workflow dĂ©passe le cadre de la fenĂȘte
  • Naviguez dans le workflow en utilisant le bouton « Vue d’ensemble » ou « Overview » situĂ©e en bas Ă  droite de l’écran
  • Remarquez en haut de l’écran, les liens permettant de naviguer dans les niveaux du workflows. Le lien indique qu’on est dans l’activitĂ© « AttenteVal » qui est elle-mĂȘme enfant d’une autre activitĂ© « StateMachine » reprĂ©sentant le workflow
  • Remarquez que l’activitĂ© est composĂ©e d’une entrĂ©e et d’une sortie (entrĂ©e de l’état et sortie de l’état).
  • L’entrĂ©e est composĂ©e d’une sĂ©quence qui est elle-mĂȘme composĂ©e d’un affiche puis d’une activitĂ© Pick. A l’intĂ©rieur de la zone « Trigger » de Pick, il y a une activitĂ© « Attendre ».
  • L’activitĂ© « Attendre » n’est pas une activitĂ© native. C’est une activitĂ© que nous avons nous-mĂȘmes dĂ©veloppĂ©s. Son implĂ©mentation est dans le fichier « Attendre.cs »
public sealed class Attendre : NativeActivity<object>
    {
        protected override void Execute(NativeActivityContext context)
        {
            context.CreateBookmark("signet");
 
 
        }
 
        protected override bool CanInduceIdle
        {
            get
            {
                return true;
            }
        }        
    }
  • Remarquez la prĂ©sence de l’activitĂ© « Attendre » dans la boĂźte Ă  outils
  • L’activitĂ© attendre crĂ©e un signet (Bookmark) qui bloque le workflow en attendant une action de l’utilisateur . DĂšs qu’un utilisateur tape une touche, le workflow reprend son activitĂ©.
  • Remarque dans « Program.cs » que le workflow n’est pas exĂ©cutĂ© par WorkflowInvoker mais par la classe « WorkflowApplication »
  var w3 = new TransactionValidationWorkflow();
            w3.Montant = 59000;
            var app = new WorkflowApplication(w3);
            app.Run();
            Console.WriteLine("appuyez sur une touche pour valider le workflow");
            Console.ReadKey();
            app.ResumeBookmark("signet", null);

Etape 5 : AccÚs à un workflow créé par code

L’objectif de cette Ă©tape est de voir comment un workflow est crĂ©Ă© par code sans passer par le designer.

  • A partir de l’explorateur de solutions, ouvrez le fichier « Program.cs »
  • Consultez la mĂ©thode « GetCodeWorkflow »
private static Activity GetCodeWorkflow()
        {
            var workflow = new Sequence()
            {
            };
            workflow.Activities.Add(new WriteLine()
            {
                Text = "Un workflow créé par code !"
            });
            return workflow;
        }
  • La mĂ©thode crĂ©e une activitĂ© de type « Sequence » puis ajoute une activitĂ© « WriteLine » a ses enfants
  • Le workflow est normalement exĂ©cutĂ© par « WorkflowInvoker » comme pour les workflows crĂ©Ă©s par designer
var w4 = GetCodeWorkflow();
WorkflowInvoker.Invoke(w4);

Etape 6 : Chargement d’un workflow à partir d’un fichier

L’objectif de cette Ă©tape est de crĂ©er un workflow qui a Ă©tĂ© ultĂ©rieurement enregistrĂ© dans un fichier « XAML ».

  • Dans l’explorateur de solutions, cliquez sur le bouton droit sur le projet « Demo1 »
  • Cliqez sur « Ouvrir le dossier dans l’explorateur de fichiers »
  • Dans l’explorateur accĂ©dez au dossier « bin Ă  debug »
  • Ouvrez le fichier « wf5.xaml » dans le bloc notes et examinez son contenu
<Activity mc:Ignorable="sap sap2010 sads" x:Class="Demo1.XmlWorkflow" sap2010:ExpressionActivityEditor.ExpressionActivityEditor="C#"
 xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:sads="http://schemas.microsoft.com/netfx/2010/xaml/activities/debugger"
 xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
 xmlns:sap2010="http://schemas.microsoft.com/netfx/2010/xaml/activities/presentation"
 xmlns:sco="clr-namespace:System.Collections.ObjectModel;assembly=mscorlib"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <TextExpression.NamespacesForImplementation>
    <sco:Collection x:TypeArguments="x:String">
      <x:String>System</x:String>
      <x:String>System.Collections.Generic</x:String>
      <x:String>System.Data</x:String>
      <x:String>System.Linq</x:String>
      <x:String>System.Text</x:String>
    </sco:Collection>
  </TextExpression.NamespacesForImplementation>
  <TextExpression.ReferencesForImplementation>
    <sco:Collection x:TypeArguments="AssemblyReference">
      <AssemblyReference>Microsoft.CSharp</AssemblyReference>
      <AssemblyReference>System</AssemblyReference>
      <AssemblyReference>System.Activities</AssemblyReference>
      <AssemblyReference>System.Core</AssemblyReference>
      <AssemblyReference>System.Data</AssemblyReference>
      <AssemblyReference>System.Runtime.Serialization</AssemblyReference>
      <AssemblyReference>System.ServiceModel</AssemblyReference>
      <AssemblyReference>System.ServiceModel.Activities</AssemblyReference>
      <AssemblyReference>System.Xaml</AssemblyReference>
      <AssemblyReference>System.Xml</AssemblyReference>
      <AssemblyReference>System.Xml.Linq</AssemblyReference>
      <AssemblyReference>mscorlib</AssemblyReference>
      <AssemblyReference>Demo1</AssemblyReference>
    </sco:Collection>
  </TextExpression.ReferencesForImplementation>
  <WriteLine Text="Un workflow chargé à partir d'un fichier" sap2010:WorkflowViewState.IdRef="WriteLine_1" sads:DebugSymbol.Symbol="dzxGOlxGb3JtYXRpb25XRlxEZW1vc1xDaGFwaXRyZSAxXERlbW8xXERlbW8xXFhtbFdvcmtmbG93LnhhbWwCIwMjlwECAQEjEyMzAgEC" />
  <sap2010:WorkflowViewState.IdRef>Demo1.XmlWorkflow_1</sap2010:WorkflowViewState.IdRef>
  <sap2010:WorkflowViewState.ViewStateManager>
    <sap2010:ViewStateManager>
      <sap2010:ViewStateData Id="WriteLine_1" sap:VirtualizedContainerService.HintSize="211,62" />
      <sap2010:ViewStateData Id="Demo1.XmlWorkflow_1" sap:VirtualizedContainerService.HintSize="251,142" />
    </sap2010:ViewStateManager>
  </sap2010:WorkflowViewState.ViewStateManager>
</Activity>
  • Revenez dans Visual Studio puis ouvrez le fichier « Program.cs »
  • Remarquez comment le workflow est chargĂ© Ă  partir du fichier prĂ©cĂ©dent
var w5 = ActivityXamlServices.Load("wf5.xaml");
WorkflowInvoker.Invoke(w5);
  • Dans le fichier xaml, changez la propriĂ©tĂ© Text de la balise WriteLine
  • RĂ©Ă©xĂ©cutez « Demo1 » pour voir le rĂ©sultat

Conclusion

Et voilĂ , en mode dĂ©couverte, vous avez vu comment exĂ©cuter plusieurs types de workflows et aussi les diffĂ©rents modes de crĂ©ation. Je reviendrai avec d’autres tutoriaux qui iront plus en dĂ©tail sur la conception de workflows.

Vous pouvez télécharger la démo ici

Enjoy ! Clignement d'Ɠil

Comments (3) -

  • Olivier PREVOT

    12/9/2015 9:22:20 AM | Reply

    Merci beaucoup pour cet article, je cherchais les grandes lignes de WF 4.5, et ça répond à une grande partie de mes premiÚres questions.

    • Amine

      12/23/2015 9:39:24 AM | Reply

      Merci

      Il faut noter que WF est la base mais pour les nouveaux projets, il faut dĂ©velopper sous Workflow Manager qui philosophiquement c'est la mĂȘme chose mais infrastructurellement diffĂ©rent. J'Ă©crirai dessus si j'ai un peu de temps inchallah.
      Bon courage !

  • Saber

    9/17/2019 2:05:08 PM | Reply

    Merci beaucoup pour cet article et tous les autres sur WF, par contre je n'arrive pas à télécharger le code source des tutoriaux.

Loading