Procédure : héberger plusieurs versions d’un workflow côte à côte
WorkflowIdentity
permet aux développeurs d'applications de workflow d'associer un nom et une version à une définition de workflow, et d'associer ces informations à une instance persistante de workflow. Ces informations d'identité peuvent être utilisées par les développeurs d'applications de workflow pour activer des scénarios tels que l'exécution côte à côte de plusieurs versions d'une définition de workflow, et fournir la base d'autres fonctionnalités telles que la mise à jour dynamique. Cette étape du didacticiel explique comment utiliser WorkflowIdentity
pour héberger plusieurs versions de workflow en même temps.
Dans cette rubrique
Dans cette étape du didacticiel, les activités WriteLine
dans le workflow sont modifiées pour fournir des informations supplémentaires, et une nouvelle activité WriteLine
est ajoutée. Une copie de l'assembly de workflow d'origine est enregistrée, et l'application hôte est mise à jour afin qu'elle puisse exécuter simultanément les workflows d'origine et mis à jour.
Pour effectuer une copie du projet NumberGuessWorkflowActivities
Pour mettre à jour WorkflowVersionMap de façon à inclure les versions précédentes de workflow
Notes
Avant de suivre les étapes de cette rubrique, exécutez l'application, démarrez plusieurs workflows de chaque type et effectuez une ou deux propositions pour chacun. Ces workflows persistants sont utilisés à cette étape et l’étape suivante, Comment mettre à jour la définition d’une instance de workflow en cours d’exécution.
Pour effectuer une copie du projet NumberGuessWorkflowActivities
Ouvrez la solution WF45GettingStartedTutorial dans Visual Studio 2012 si elle n’est pas ouverte.
Appuyez sur Ctrl+Maj+B pour générer la solution.
Fermez la solution WF45GettingStartedTutorial.
Ouvrez l’Explorateur Windows et accédez au répertoire dans lequel le fichier solution du didacticiel et les dossiers du projet sont situés.
Créez un dossier nommé PreviousVersions dans le même dossier que NumberGuessWorkflowHost et NumberGuessWorkflowActivities. Ce dossier est utilisé pour contenir les assemblys qui contiennent les différentes versions de workflow utilisées dans les étapes du didacticiel suivantes.
Accédez au dossier NumberGuessWorkflowActivities\bin\debug (ou bin\release selon les paramètres de votre projet). Copiez NumberGuessWorkflowActivities.dll et collez-le dans le dossier PreviousVersions.
Renommez NumberGuessWorkflowActivities.dll dans le dossier PreviousVersions en NumberGuessWorkflowActivities_v1.dll.
Notes
Les étapes de cette rubrique illustrent une façon de gérer les assemblys utilisés pour contenir plusieurs versions de workflow. D'autres méthodes, telles que celles d'attribution de nom fort aux assemblys et d'inscription des assemblys dans le Global Assembly Cache peuvent également être utilisées.
Créez un dossier nommé NumberGuessWorkflowActivities_du dans le même dossier que NumberGuessWorkflowHost, NumberGuessWorkflowActivities, et le dossier que vous venez d’ajouter PreviousVersions, puis copiez tous les fichiers et sous-dossiers du dossier NumberGuessWorkflowActivities dans le nouveau dossier NumberGuessWorkflowActivities_du. Cette copie de sauvegarde du projet pour la version initiale des activités est utilisée dans Comment mettre à jour la définition d’une instance de workflow en cours d’exécution.
Rouvrez la solution WF45GettingStartedTutorial dans Visual Studio 2012.
Pour mettre à jour les workflows
Dans cette section, les définitions de workflow sont mises à jour. Les deux activités WriteLine
qui fournissent des commentaires sur la proposition de l'utilisateur sont mises à jour, et une nouvelle activité WriteLine
, qui fournit des informations supplémentaires sur le jeu une fois que le nombre est deviné, est ajoutée.
Pour mettre à jour le workflow StateMachine
Dans l’Explorateur de solutions, sous le projet NumberGuessWorkflowActivities, double-cliquez sur StateMachineNumberGuessWorkflow.xaml.
Double-cliquez sur la transition Guess Incorrect sur la machine à états.
Mettez à jour la propriété
Text
de l'activitéWriteLine
située le plus à gauche dans l'activitéIf
.Guess & " is too low."
Guess + " is too low."
Mettez à jour la propriété
Text
de l'activitéWriteLine
située le plus à droite dans l'activitéIf
.Guess & " is too high."
Guess + " is too high."
Revenez à la vue générale de la machine à états dans le concepteur de workflow en cliquant sur StateMachine dans la navigation en haut du concepteur de workflow.
Double-cliquez sur la transition Guess Correct sur la machine à états.
Faites glisser une activité WriteLine de la section Primitives de la Boîte à outils et déposez-la sur l’étiquette Déposer l’activité d’action ici de la transition.
Dans la zone de propriété
Text
, tapez l'expression suivante :Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Pour mettre à jour le workflow Flowchart
Dans l’Explorateur de solutions, sous le projet NumberGuessWorkflowActivities, double-cliquez sur FlowchartNumberGuessWorkflow.xaml.
Mettez à jour la propriété
Text
de l'activitéWriteLine
située le plus à gauche.Guess & " is too low."
Guess + " is too low."
Mettez à jour la propriété
Text
de l'activitéWriteLine
située le plus à droite.Guess & " is too high."
Guess + " is too high."
Faites glisser une activité WriteLine de la section Primitives de la Boîte à outils et déposez-la sur le point de dépôt de l’action
True
duFlowDecision
le plus haut. L'activitéWriteLine
est ajoutée à l'organigramme et liée à l'actionTrue
deFlowDecision
.Dans la zone de propriété
Text
, tapez l'expression suivante :Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Pour mettre à jour le workflow séquentiel
Dans l’Explorateur de solutions, sous le projet NumberGuessWorkflowActivities, double-cliquez sur SequentialNumberGuessWorkflow.xaml.
Mettez à jour la propriété
Text
de l'activitéWriteLine
située le plus à gauche dans l'activitéIf
.Guess & " is too low."
Guess + " is too low."
Mettez à jour la propriété
Text
de l'activitéWriteLine
située le plus à droite dans l'activitéIf
.Guess & " is too high."
Guess + " is too high."
Faites glisser une activité WriteLine de la section Primitives de la Boîte à outils et déposez-la après l’activité DoWhile afin que WriteLine soit l’activité finale dans l’activité
Sequence
racine.Dans la zone de propriété
Text
, tapez l'expression suivante :Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Pour mettre à jour WorkflowVersionMap de façon à inclure les versions précédentes de workflow
Double-cliquez sur WorkflowVersionMap.cs (ou WorkflowVersionMap.vb) sous le projet NumberGuessWorkflowHost pour l’ouvrir.
Ajoutez les instructions
using
(ouImports
) suivantes au début du fichier avec les autres instructionsusing
(ouImports
).Imports System.Reflection Imports System.IO
using System.Reflection; using System.IO;
Ajoutez trois nouvelles identités de workflow juste au-dessous des trois déclarations d'identité de workflow existantes. Ces nouvelles identités de workflow
v1
seront utilisées pour fournir la définition appropriée de workflow aux workflows démarrés avant que les mises à jour aient été effectuées.'Current version identities. Public StateMachineNumberGuessIdentity As WorkflowIdentity Public FlowchartNumberGuessIdentity As WorkflowIdentity Public SequentialNumberGuessIdentity As WorkflowIdentity 'v1 Identities. Public StateMachineNumberGuessIdentity_v1 As WorkflowIdentity Public FlowchartNumberGuessIdentity_v1 As WorkflowIdentity Public SequentialNumberGuessIdentity_v1 As WorkflowIdentity
// Current version identities. static public WorkflowIdentity StateMachineNumberGuessIdentity; static public WorkflowIdentity FlowchartNumberGuessIdentity; static public WorkflowIdentity SequentialNumberGuessIdentity; // v1 identities. static public WorkflowIdentity StateMachineNumberGuessIdentity_v1; static public WorkflowIdentity FlowchartNumberGuessIdentity_v1; static public WorkflowIdentity SequentialNumberGuessIdentity_v1;
Dans le constructeur
WorkflowVersionMap
, mettez à jour la propriétéVersion
des trois identités actuelles de workflow vers2.0.0.0
.'Add the current workflow version identities. StateMachineNumberGuessIdentity = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } FlowchartNumberGuessIdentity = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } SequentialNumberGuessIdentity = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow()) map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow()) map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow())
// Add the current workflow version identities. StateMachineNumberGuessIdentity = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; FlowchartNumberGuessIdentity = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; SequentialNumberGuessIdentity = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow()); map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow()); map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow());
Le code qui ajoute les versions actuelles des workflow au dictionnaire utilise les versions actuelles qui sont référencées dans le projet ainsi, le code qui initialise les définitions de workflow n'a pas besoin d'être mis à jour.
Ajoutez le code suivant dans le constructeur juste après le code qui ajoute les versions actuelles au dictionnaire.
'Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } FlowchartNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } SequentialNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) }
// Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; FlowchartNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; SequentialNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) };
Ces identités de workflow sont associées aux versions initiales des définitions correspondantes de workflow.
Ensuite, chargez l'assembly qui contient la première version des définitions de workflow, puis créez et ajoutez des définitions correspondantes de workflow au dictionnaire.
'Add the previous version workflow identities to the dictionary along with 'the corresponding workflow definitions loaded from the v1 assembly. 'Assembly.LoadFile requires an absolute path so convert this relative path 'to an absolute path. Dim v1AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll" v1AssemblyPath = Path.GetFullPath(v1AssemblyPath) Dim v1Assembly As Assembly = Assembly.LoadFile(v1AssemblyPath) map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow")) map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow")) map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow"))
// Add the previous version workflow identities to the dictionary along with // the corresponding workflow definitions loaded from the v1 assembly. // Assembly.LoadFile requires an absolute path so convert this relative path // to an absolute path. string v1AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll"; v1AssemblyPath = Path.GetFullPath(v1AssemblyPath); Assembly v1Assembly = Assembly.LoadFile(v1AssemblyPath); map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity); map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity); map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity);
L'exemple suivant constitue l'intégralité de la classe
WorkflowVersionMap
mise à jour.Public Module WorkflowVersionMap Dim map As Dictionary(Of WorkflowIdentity, Activity) 'Current version identities. Public StateMachineNumberGuessIdentity As WorkflowIdentity Public FlowchartNumberGuessIdentity As WorkflowIdentity Public SequentialNumberGuessIdentity As WorkflowIdentity 'v1 Identities. Public StateMachineNumberGuessIdentity_v1 As WorkflowIdentity Public FlowchartNumberGuessIdentity_v1 As WorkflowIdentity Public SequentialNumberGuessIdentity_v1 As WorkflowIdentity Sub New() map = New Dictionary(Of WorkflowIdentity, Activity) 'Add the current workflow version identities. StateMachineNumberGuessIdentity = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } FlowchartNumberGuessIdentity = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } SequentialNumberGuessIdentity = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow()) map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow()) map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow()) 'Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } FlowchartNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } SequentialNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } 'Add the previous version workflow identities to the dictionary along with 'the corresponding workflow definitions loaded from the v1 assembly. 'Assembly.LoadFile requires an absolute path so convert this relative path 'to an absolute path. Dim v1AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll" v1AssemblyPath = Path.GetFullPath(v1AssemblyPath) Dim v1Assembly As Assembly = Assembly.LoadFile(v1AssemblyPath) map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow")) map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow")) map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow")) End Sub Public Function GetWorkflowDefinition(identity As WorkflowIdentity) As Activity Return map(identity) End Function Public Function GetIdentityDescription(identity As WorkflowIdentity) As String Return identity.ToString() End Function End Module
public static class WorkflowVersionMap { static Dictionary<WorkflowIdentity, Activity> map; // Current version identities. static public WorkflowIdentity StateMachineNumberGuessIdentity; static public WorkflowIdentity FlowchartNumberGuessIdentity; static public WorkflowIdentity SequentialNumberGuessIdentity; // v1 identities. static public WorkflowIdentity StateMachineNumberGuessIdentity_v1; static public WorkflowIdentity FlowchartNumberGuessIdentity_v1; static public WorkflowIdentity SequentialNumberGuessIdentity_v1; static WorkflowVersionMap() { map = new Dictionary<WorkflowIdentity, Activity>(); // Add the current workflow version identities. StateMachineNumberGuessIdentity = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; FlowchartNumberGuessIdentity = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; SequentialNumberGuessIdentity = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow()); map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow()); map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow()); // Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; FlowchartNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; SequentialNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; // Add the previous version workflow identities to the dictionary along with // the corresponding workflow definitions loaded from the v1 assembly. // Assembly.LoadFile requires an absolute path so convert this relative path // to an absolute path. string v1AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll"; v1AssemblyPath = Path.GetFullPath(v1AssemblyPath); Assembly v1Assembly = Assembly.LoadFile(v1AssemblyPath); map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity); map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity); map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity); } public static Activity GetWorkflowDefinition(WorkflowIdentity identity) { return map[identity]; } public static string GetIdentityDescription(WorkflowIdentity identity) { return identity.ToString(); } }
Pour générer et exécuter l'application
Appuyez sur Ctrl+Maj+B pour générer l'application, puis sur Ctrl+F5 pour démarrer.
Commencez un nouveau workflow en cliquant sur New Game. La version du workflow s'affiche dans la fenêtre d'état et reflète la version mise à jour du
WorkflowIdentity
associé. NotezInstanceId
de façon à afficher le fichier de suivi du workflow lorsqu'il se termine, puis entrez des propositions jusqu'à ce que le jeu soit terminé. Notez comment la proposition de l'utilisateur est affichée dans les informations affichées dans la fenêtre d'état basée sur les mises à jour dans les activitésWriteLine
.Please enter a number between 1 and 10 5 is too high. Please enter a number between 1 and 10 3 is too high. Please enter a number between 1 and 10 1 is too low. Please enter a number between 1 and 10 Congratulations, you guessed the number in 4 turns.
Notes
Le texte mis à jour à partir des activités
WriteLine
s'affiche, mais la sortie de l'activité finaleWriteLine
ajoutée dans cette rubrique ne s'affiche pas. Cela est dû au fait que la fenêtre d'état est mise à jour par le gestionnairePersistableIdle
. Étant donné que le workflow se termine et n'est pas inactif après l'activité finale, le gestionnairePersistableIdle
n'est pas appelé. Toutefois, un message similaire est affiché dans la fenêtre d'état par le gestionnaireCompleted
. Si vous le souhaitez, le code peut être ajouté au gestionnaireCompleted
pour extraire le texte deStringWriter
et pour l'afficher dans la fenêtre d'état.Ouvrez l’Explorateur Windows et accédez au dossier NumberGuessWorkflowHost\bin\debug (ou bin\release selon les paramètres du projet), puis ouvrez dans le Bloc-notes le fichier de suivi qui correspond au workflow terminé. Si vous n’avez pas noté l’
InstanceId
, vous pouvez identifier le fichier de suivi approprié à partir de l’information Date de modification dans l’Explorateur Windows.Please enter a number between 1 and 10 5 is too high. Please enter a number between 1 and 10 3 is too high. Please enter a number between 1 and 10 1 is too low. Please enter a number between 1 and 10 2 is correct. You guessed it in 4 turns.
La sortie mise à jour
WriteLine
est contenue dans le fichier de trace, y compris la sortieWriteLine
ajoutée dans cette rubrique.Revenez à l'application d'estimation de nombre et sélectionnez l'un des workflows qui a été démarré avant que les mises à jour n'aient été effectuées. Vous pouvez identifier la version du workflow actuellement sélectionné en examinant les informations de version qui s'affichent sous la fenêtre d'état. Entrez des propositions et notez que les mises à jour d'état correspondent à la sortie d'activité
WriteLine
de la version antérieure, et n'incluez pas l'estimation de l'utilisateur. Cela est dû au fait que ces workflows utilisent la définition de workflow précédente qui n'a pas les mises à jour deWriteLine
.À l’étape suivante, Comment mettre à jour la définition d’une instance de workflow en cours d’exécution, les instances de workflow
v1
en cours d’exécution sont mises à jour afin qu’elles contiennent les nouvelles fonctionnalités comme les instancesv2
.