Partager via


Tâche 2 : créer un client de service de workflow

Dans cette tâche, vous allez créer un client de service de workflow de base qui appelle les opérations définies et implémentées dans le service de workflow que vous avez créé dans Tâche 1 : créer le service de workflow. Le client affiche dans une fenêtre de console la valeur qu'il a passée dans chaque appel de l'opération mathématique et ce que le service a renvoyé dans la réponse.

Bb924504.note(fr-fr,VS.90).gifRemarque :
Ce client est utilisé dans les exercices restants de ce didacticiel.

Bb924504.note(fr-fr,VS.90).gifRemarque :
Lorsque le concepteur de flux de travail de Visual Studio est utilisé pour créer ou gérer des services de flux de travail, il produit parfois des erreurs de validation parasites. Si vous êtes en mesure de générer votre projet avec succès, ignorez les erreurs de validation.

Pour créer le client du service du workflow

  1. Si la solution WorkflowServiceTutorial n'est pas ouverte, ouvrez Visual Studio 2008, cliquez sur Fichier, mettez en surbrillance Ouvriret naviguez jusqu'à la solution WorkflowServiceTutorial.

  2. Si WcfSvcHost.exe n'est pas exécuté, appuyez sur CTRL + F5 pour générer et exécuter le service WorkflowServiceTutorial. Ce service doit être exécuté pour effectuer les étapes de cette tâche. Dans la liste Service, cliquez avec le bouton droit sur WorkflowServiceTutorial.ServerWorkflow, puis sélectionnez Copier l'adresse des métadonnées.

  3. Cliquez sur Fichier, mettez en surbrillance Ajouter et sélectionnez Nouveau projet.

  4. Dans la boîte de dialogue Nouveau projet, sous Workflow, sélectionnez Application console de workflow séquentiel.

  5. Nommez le projet WorkflowServiceClient, puis cliquez sur OK.

  6. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le nœud WorkflowServiceClient, puis sélectionnez Ajouter une référence de service.

    Collez l'adresse des métadonnées que vous avez copiée précédemment dans la zone Adresse de la boîte de dialogue Ajouter une référence de service, puis cliquez sur Aller à. Une fois que ServerWorkflow s'affiche dans la zone Services, cliquez sur OK pour ajouter la référence de service.

  7. Ouvrez la page du concepteur de workflow pour votre workflow et ajoutez une activité SendActivity à votre workflow à l'aide du volet Boîte à outils.

  8. Mettez en surbrillance l'activité SendActivity dans le concepteur de workflow.

  9. Naviguer jusqu'au volet Propriétés, sous la propriété ServiceOperationInfo, cliquez sur le bouton de sélection pour ouvrir la boîte de dialogue Choisir une opération.

  10. Dans le coin supérieur droit, cliquez sur Importer.

  11. Sous l'onglet Type, mettez en surbrillance <Projet en cours>.

  12. Sélectionnez IWorkflow1 dans la liste des types et cliquez sur OK.

    La boîte de dialogue Choisir une opération se remplira avec les informations sur le contrat et l'opération définies par le modèle et implémentées par vos soins dans le projet WorkflowServiceTutorial.

  13. Sous Opérations disponibles, mettez en surbrillance StartupService, puis cliquez sur OK.

    Le concepteur associe l'activité SendActivity à l'opération StartupService en créant un objet TypedOperationInfo, en le remplissant avec les informations sur le contrat et l'opération et en l'associant à votre activité SendActivity à l'aide de la propriété ServiceOperationInfo.

  14. Dans le concepteur de workflow, naviguez jusqu'au volet Propriétés.

  15. Dans la propriété ChannelToken, créez le nom de l'objet ChannelToken, puis appuyez sur ENTRÉE.

  16. Développez la propriété ChannelToken.

  17. Pour la propriété EndpointName, naviguez jusqu'au fichier App.config du client. Copiez et collez le nom du point de terminaison que vous souhaitez utiliser pour accéder au service. Par exemple, le nom du point de terminaison est "WSHttpContextBinding_IWorkflow1" dans le code suivant.

    <client>
        <endpoint address="https://localhost:8080/ServerWorkflow" binding="wsHttpContextBinding"
            bindingConfiguration="WSHttpContextBinding_IWorkflow1" contract="ServiceReference.IWorkflow1"
            name="WSHttpContextBinding_IWorkflow1">
            <identity>
                <userPrincipalName value="someone@example.com" />
            </identity>
        </endpoint>
    </client>
    
    Bb924504.note(fr-fr,VS.90).gifRemarque :
    La propriété EndpointName et l'attribut de nom de votre fichier App.config doivent être les mêmes ou vous recevrez des messages d'erreur lors de l'exécution de votre application cliente.

  18. Laissez la zone de la propriété OwnerActivityName vide. En ne sélectionnant aucun nom, le nom de l'activité racine sera sélectionné pour vous au moment de la compilation.

  19. Dans le volet Propriétés, cliquez sur le bouton Événements.

  20. Double-cliquez dans la zone de texte pour que l'événement AfterResponse génère un gestionnaire d'événements.

  21. Entrez le code suivant pour que le message suivant s'affiche pour l'utilisateur lorsque l'opération StartupService aura été appelée.

    Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("A service instance has successfully been created.")
        End Sub
    
    private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
    {
        Console.WriteLine("A service instance has successfully been created.");
    }
    
  22. Dans le concepteur de workflow, ajoutez cinq activités SendActivity supplémentaires.

  23. Associez chaque activité SendActivity à une opération et le même jeton de canal client que vous avez utilisé aux étapes 13 à 17.

  24. Du fait que les opérations mathématiques (Additionner, Soustraire, Multiplier, Diviser) prennent un int nommé n1, vous devez créer une activité qui lie à n1 ou lui définir une valeur. Dans ce didacticiel, nous allons créer une liaison avec une propriété existante dans notre workflow. Pour ce faire, ouvrez Workflow1.cs (ou Workflow1.vb si vous avez créé une solution Visual Basic) et effectuez les étapes suivantes :

    1. Renommez la classe Workflow1 à ClientWorkflow.

    2. Dans la définition de classe ClientWorkflow, créez une propriété publique telle qu'affichée dans l'exemple suivant :

      Public class ClientWorkflow
          Inherits SequentialWorkflowActivity
      
          Public inputValue As Integer = Nothing
      
          Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
              Console.WriteLine("A service instance has successfully been created.")
          End Sub
      End Class
      
      public sealed partial class ClientWorkflow: SequentialWorkflowActivity
      {
          public int inputValue = default(int);
      
          public ClientWorkflow()
          {
              InitializeComponent();
          }
      
          private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
          {
              Console.WriteLine("A service instance has successfully been created.");
          }
      }
      
    3. Ouvrez le concepteur de flux de travail et, dans le volet Propriétés de l'activité SendActivity associée à l'appel de l'opération Add, liez inputValue à la propriété de l'activité n1 en cliquant sur les points de suspension et en sélectionnant inputValue dans l'onglet Lier à un membre existant.

    4. Implémentez un gestionnaire d'événements pour l'événement BeforeSend afin de créer le message à envoyer au service.

      Private Sub sendActivity2_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
          inputValue = 1
          Console.WriteLine("The initial input value is {0}", inputValue)
      End Sub
      
      private void sendActivity2_BeforeSend(object sender, SendActivityEventArgs e)
      {
          inputValue = 1;
          Console.WriteLine("The initial input value is {0}", inputValue);
      }
      
  25. Pour afficher à nouveau les résultats du service, vous devez créer une variable permettant de maintenir la valeur de retour lorsque l'opération réussit. Pour ce faire, ouvrez Workflow1.cs (ou Workflow1.vb si vous avez créé une solution Visual Basic) et effectuez les étapes suivantes :

    1. Dans la définition de classe ClientWorkflow, créez une propriété publique nommée returnedValue, comme indiqué dans l'exemple suivant :

      Public class ClientWorkflow
          Inherits SequentialWorkflowActivity
      
          Public inputValue As Integer = Nothing
          Public returnedValue As Integer = Nothing
      ...
      End Class
      
      public sealed partial class ClientWorkflow: SequentialWorkflowActivity
      {
          public int inputValue = default(int);
          public int returnedValue = default(int);
      
          public ClientWorkflow()
          {
              InitializeComponent();
          }
      ...
      }
      
    2. Ouvrez le concepteur de flux de travail et, dans le volet Propriétés, liez returnedValue à la propriété d'activité (ReturnValue) en cliquant sur les points de suspension et en sélectionnant returnedValue dans l'onglet Lier à un membre existant.

    3. Implémentez un gestionnaire d'événements pour l'événement AfterResponse afin de consulter le message renvoyé par le service.

      private void sendActivity2_AfterResponse(object sender, SendActivityEventArgs e)
      {
          Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue); 
      }
      
  26. Pour chacune des autres opérations mathématiques, liez respectivement inputValue et returnedValue à n1 et (ReturnValue).

  27. Implémentez les gestionnaires d'événement pour les événements BeforeSend et AfterResponse dans chaque activité SendActivity restante associée à une opération mathématique, comme aux étapes 24c et 25c. L'exemple suivant présente l'implémentation de tous les gestionnaires d'événements, y compris celui de l'activité SendActivity associée à l'opération ShutdownService.

        Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("A service instance has successfully been created.")
        End Sub
    
        Private Sub sendActivity2_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 1
            Console.WriteLine("The initial input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity2_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity3_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 2
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity3_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Subtract operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity4_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 6
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity4_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Multiply operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity5_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 3
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity5_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Divide operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity6_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The workflow service instance has been successfully shut down.")
        End Sub
    
        private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("A service instance has successfully been created.");
        }
    
        private void sendActivity2_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 1;
            Console.WriteLine("The initial input value is {0}", inputValue);
        }
    
        private void sendActivity2_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue);
        }
    
        private void sendActivity3_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 2;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity3_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Subtract operation is {0}", returnedValue);
        }
    
        private void sendActivity4_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 6;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity4_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Multiply operation is {0}", returnedValue);
        }
    
        private void sendActivity5_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 3;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity5_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Divide operation is {0}", returnedValue);
        }
    
        private void sendActivity6_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The workflow service instance has been successfully shut down.");
        }
    
  28. Dans Program.cs (ou Module1.vb en Visual Basic), ajoutez le ChannelManagerService à la liste de services utilisée par le WorkflowRuntime pour mettre en cache des canaux et fabrications de canaux. L'utilisation du ChannelManagerService est facultatif, mais si vous ne l'utilisez pas, les canaux ne seront pas mis en cache et chaque activité SendActivity d'un workflow utilisera une nouvelle instance de canal lors de communications avec le service.

    Shared WaitHandle As New AutoResetEvent(False)
    
    Shared Sub Main()
        Using workflowRuntime As New WorkflowRuntime()
            AddHandler workflowRuntime.WorkflowCompleted, AddressOf OnWorkflowCompleted
            AddHandler workflowRuntime.WorkflowTerminated, AddressOf OnWorkflowTerminated
    
            ' Add ChannelManagerService to the list of services used by the WorkflowRuntime.
            Dim cms As ChannelManagerService = New ChannelManagerService()workflowRuntime.AddService(cms)
    
            Dim workflowInstance As WorkflowInstance
            workflowInstance = workflowRuntime.CreateWorkflow(GetType(ClientWorkflow))
            workflowInstance.Start()
            WaitHandle.WaitOne()
        End Using
    End Sub
    Shared Sub OnWorkflowCompleted(ByVal sender As Object, ByVal e As WorkflowCompletedEventArgs)
        Console.WriteLine("The client workflow has completed." + vbLf + "Press <Enter> to exit the client application.")
        Console.ReadLine()
        WaitHandle.Set()
    End Sub
    
    Shared Sub OnWorkflowTerminated(ByVal sender As Object, ByVal e As WorkflowTerminatedEventArgs)
        Console.WriteLine(e.Exception.Message)
        WaitHandle.Set()
    End Sub
    
    using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
    {
        AutoResetEvent waitHandle = new AutoResetEvent(false);
    
        // Add ChannelManagerService to the list of services used 
        // by the WorkflowRuntime.
        ChannelManagerService cms = new ChannelManagerService();    workflowRuntime.AddService(cms);
    
        workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) 
        {
            Console.WriteLine("The client workflow has completed. \nPress <Enter> to exit the client application."); 
            Console.ReadLine(); 
            waitHandle.Set(); 
        };
    
        workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
            waitHandle.Set();
        };
    
        WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowServiceClient.ClientWorkflow));
        instance.Start();
    
        waitHandle.WaitOne();
    }
    
  29. Pour utiliser le client avec votre service de workflow dans la solution WorkflowServiceTutorial créée dans l'exercice 1, vous devez supprimer un argument de la ligne de commande des propriétés du projet WorkflowServiceTutorial. Pour cela, effectuez les étapes suivantes :

    1. Cliquez avec le bouton droit sur le nœud du projet WorkflowServiceTutorial et sélectionnez Propriétés.
    2. Sélectionnez l'onglet Débogage, et dans le volet d'informations sous Démarrer Options, supprimez /client:"WfcTestClient.exe" de la zone de texte.
  30. Cliquez avec le bouton droit sur le nœud de la solution WorkflowServiceTutorial et sélectionnez Propriétés.

  31. Dans la boîte de dialogue Pages de propriétés, sélectionnez Plusieurs projets de démarrage.

  32. Si WorkflowServiceTutorial n'est pas répertorié comme élément supérieur dans la liste, utilisez les flèches sur le côté de la zone de liste pour en faire l'élément supérieur. Cette opération est indispensable pour que votre service commence à s'exécuter avant que votre application cliente essaie d'appeler toutes opérations sur le service.

  33. Pour chaque projet de la liste, modifiez l'action de Aucun à Démarrer.

  34. Cliquez sur Appliquer, puis sur OK.

  35. Si vous avez créé une solution Visual Basic, dans le volet Explorateur de solutions, cliquez avec le bouton droit sur le nœud du projet WorkflowServiceClient et sélectionnez Propriétés.

  36. Sélectionnez l'onglet Application et supprimez WorkflowServiceClient de la zone de texte Espace de noms racine. Si vous ne le faites pas, vous ne serez pas en mesure de vous connecter au service de workflow parce que le client référencera un espace de noms incorrect.

  37. Générez et exécutez la solution du service de workflow.

  38. Après avoir démarré le service, l'application cliente s'exécute. Vous devez observer ce qui suit lors de l'exécution de votre application cliente à partir de l'invite de commandes.

    A workflow service instance has successfully been created.
    The initial input value is 1
    The value after invoking the Add operation is 1
    The new input value is 2
    The value after invoking the Subract operation is -1
    The new input value is 6
    The value after invoking the Multiply operation is -6
    The new input value is 3
    The value after invoking the Divide operation is -2
    The workflow service instance has been successfully shut down.
    The client workflow has completed. 
    Press <Enter> to exit the client application.
    

Voir aussi

Autres ressources

Exercice 1 : créer un service de workflow de base

Copyright © 2007 par Microsoft Corporation. Tous droits réservés.