Partager via


Mise à jour dynamique

La mise à jour dynamique fournit un mécanisme permettant aux développeurs d’applications de flux de travail de mettre à jour la définition de workflow d’une instance de flux de travail persistante. Il peut s’agir d’implémenter un correctif de bogues, de nouvelles exigences ou de prendre en charge des modifications inattendues. Cette rubrique fournit une vue d’ensemble de la fonctionnalité de mise à jour dynamique introduite dans .NET Framework 4.5.

Pour appliquer des mises à jour dynamiques à une instance de flux de travail persistante, il DynamicUpdateMap est créé qui contient des instructions pour le runtime qui décrivent comment modifier l’instance de flux de travail persistante pour refléter les modifications souhaitées. Une fois la carte de mise à jour créée, elle est appliquée aux instances de workflow persistantes souhaitées. Une fois la mise à jour dynamique appliquée, l’instance de flux de travail peut être reprise à l’aide de la nouvelle définition de flux de travail mise à jour. Il existe quatre étapes requises pour créer et appliquer une carte de mise à jour.

  1. Préparez la définition de flux de travail pour la mise à jour dynamique.
  2. Mettez à jour la définition du flux de travail pour refléter les modifications souhaitées.
  3. Créez la carte de mise à jour.
  4. Appliquez le mappage de mise à jour aux instances de flux de travail persistantes souhaitées.

Remarque

Les étapes 1 à 3, qui couvrent la création de la carte de mise à jour, peuvent être effectuées indépendamment de l’application de la mise à jour. Un scénario courant est que le développeur de flux de travail crée la carte de mise à jour hors connexion, puis qu’un administrateur applique la mise à jour ultérieurement.

Cet article fournit une vue d’ensemble du processus de mise à jour dynamique de l’ajout d’une nouvelle activité à une instance persistante d’un flux de travail Xaml compilé.

Préparer la définition du flux de travail pour la mise à jour dynamique

La première étape du processus de mise à jour dynamique consiste à préparer la définition de flux de travail souhaitée pour la mise à jour. Pour ce faire, appelez la DynamicUpdateServices.PrepareForUpdate méthode et transmettez la définition de workflow à modifier. Cette méthode valide, puis guide l’arborescence de flux de travail pour identifier tous les objets tels que les activités publiques et les variables qui doivent être étiquetées afin qu’ils puissent être comparés ultérieurement à la définition de flux de travail modifiée. Une fois cette opération terminée, l’arborescence de flux de travail est cloné et attaché à la définition de flux de travail d’origine. Lorsque la carte de mise à jour est créée, la version mise à jour de la définition de flux de travail est comparée à la définition de flux de travail d’origine et la carte de mise à jour est générée en fonction des différences.

Pour préparer un flux de travail Xaml pour la mise à jour dynamique, il peut être chargé dans un ActivityBuilder, puis il ActivityBuilder est passé dans DynamicUpdateServices.PrepareForUpdate.

Remarque

Pour plus d’informations sur l’utilisation de flux de travail sérialisés et ActivityBuilder, consultez Sérialisation des flux de travail et des activités vers et depuis XAML.

Dans l’exemple suivant, une MortgageWorkflow définition (qui se compose d’une Sequence avec plusieurs activités enfants) est chargée dans un ActivityBuilder, puis préparée pour la mise à jour dynamique. Une fois la méthode retournée, elle ActivityBuilder contient la définition de flux de travail d’origine ainsi qu’une copie.

// Load the MortgageWorkflow definition from Xaml into
// an ActivityBuilder.
XamlXmlReaderSettings readerSettings = new XamlXmlReaderSettings()
{
    LocalAssembly = Assembly.GetExecutingAssembly()
};

XamlXmlReader xamlReader = new XamlXmlReader(@"C:\WorkflowDefinitions\MortgageWorkflow.xaml",
    readerSettings);

ActivityBuilder ab = XamlServices.Load(
    ActivityXamlServices.CreateBuilderReader(xamlReader)) as ActivityBuilder;

// Prepare the workflow definition for dynamic update.
DynamicUpdateServices.PrepareForUpdate(ab);

Mettre à jour la définition du flux de travail pour refléter les modifications souhaitées

Une fois la définition de flux de travail préparée pour la mise à jour, les modifications souhaitées peuvent être apportées. Vous pouvez ajouter ou supprimer des activités, ajouter, déplacer ou supprimer des variables publiques, ajouter ou supprimer des arguments et apporter des modifications à la signature des délégués d’activité. Vous ne pouvez pas supprimer une activité en cours d’exécution ou modifier la signature d’un délégué en cours d’exécution. Ces modifications peuvent être apportées à l’aide du code ou dans un concepteur de workflow réhébergé. Dans l’exemple suivant, une activité personnalisée VerifyAppraisal est ajoutée à la séquence qui compose le corps de l’exemple MortgageWorkflow précédent.

// Make desired changes to the definition. In this example, we are
// inserting a new VerifyAppraisal activity as the 3rd child of the root Sequence.
VerifyAppraisal va = new VerifyAppraisal
{
    Result = new VisualBasicReference<bool>("LoanCriteria")
};

// Get the Sequence that makes up the body of the workflow.
Sequence s = ab.Implementation as Sequence;

// Insert the new activity into the Sequence.
s.Activities.Insert(2, va);

Créer la carte de mise à jour

Une fois que la définition de flux de travail préparée pour la mise à jour a été modifiée, la carte de mise à jour peut être créée. Pour créer une carte de mise à jour dynamique, la DynamicUpdateServices.CreateUpdateMap méthode est appelée. Cela retourne une DynamicUpdateMap valeur qui contient les informations dont le runtime a besoin pour modifier une instance de flux de travail persistante afin qu’elle puisse être chargée et reprise avec la nouvelle définition de flux de travail. Dans l’exemple suivant, une carte dynamique est créée pour la définition modifiée MortgageWorkflow de l’exemple précédent.

// Create the update map.
DynamicUpdateMap map = DynamicUpdateServices.CreateUpdateMap(ab);

Cette carte de mise à jour peut être utilisée immédiatement pour modifier les instances de flux de travail persistantes, ou plus généralement, elle peut être enregistrée et les mises à jour appliquées ultérieurement. L’une des façons d’enregistrer la carte de mise à jour consiste à la sérialiser dans un fichier, comme illustré dans l’exemple suivant.

// Serialize the update map to a file.
DataContractSerializer serializer = new DataContractSerializer(typeof(DynamicUpdateMap));
using (FileStream fs = System.IO.File.Open(@"C:\WorkflowDefinitions\MortgageWorkflow.map", FileMode.Create))
{
    serializer.WriteObject(fs, map);
}

Quand DynamicUpdateServices.CreateUpdateMap elle est retournée, la définition de flux de travail cloné et d’autres informations de mise à jour dynamique ajoutées dans l’appel à DynamicUpdateServices.PrepareForUpdate est supprimée et la définition de flux de travail modifiée est prête à être enregistrée afin qu’elle puisse être utilisée ultérieurement lors de la reprise des instances de flux de travail mises à jour. Dans l’exemple suivant, la définition de flux de travail modifiée est enregistrée dans MortgageWorkflow_v1.1.xaml.

// Save the modified workflow definition.
StreamWriter sw = File.CreateText(@"C:\WorkflowDefinitions\MortgageWorkflow_v1.1.xaml");
XamlWriter xw = ActivityXamlServices.CreateBuilderWriter(new XamlXmlWriter(sw, new XamlSchemaContext()));
XamlServices.Save(xw, ab);
sw.Close();

Appliquer le mappage de mise à jour aux instances de flux de travail persistantes souhaitées

L’application de la carte de mise à jour peut être effectuée à tout moment après sa création. Elle peut être effectuée immédiatement à l’aide de l’instance DynamicUpdateMap retournée par DynamicUpdateServices.CreateUpdateMap, ou elle peut être effectuée ultérieurement à l’aide d’une copie enregistrée du mappage de mise à jour. Pour mettre à jour une instance de workflow, chargez-la dans une WorkflowApplicationInstance utilisation WorkflowApplication.GetInstance. Ensuite, créez une WorkflowApplication utilisation de la définition de flux de travail mise à jour et de la définition souhaitée WorkflowIdentity. Cela WorkflowIdentity peut être différent de celui utilisé pour conserver le flux de travail d’origine, et il est généralement nécessaire de refléter que l’instance persistante a été modifiée. Une fois le WorkflowApplication fichier créé, il est chargé à l’aide de la surcharge qui WorkflowApplication.Load prend un DynamicUpdateMap, puis déchargé avec un appel à WorkflowApplication.Unload. Cela applique la mise à jour dynamique et conserve l’instance de workflow mise à jour.

// Load the serialized update map.
DynamicUpdateMap map;
using (FileStream fs = File.Open(@"C:\WorkflowDefinitions\MortgageWorkflow.map", FileMode.Open))
{
    DataContractSerializer serializer = new DataContractSerializer(typeof(DynamicUpdateMap));
    object updateMap = serializer.ReadObject(fs);
    if (updateMap == null)
    {
        throw new ApplicationException("DynamicUpdateMap is null.");
    }

    map = (DynamicUpdateMap)updateMap;
}

// Retrieve a list of workflow instance ids that corresponds to the
// workflow instances to update. This step is the responsibility of
// the application developer.
List<Guid> ids = GetPersistedWorkflowIds();
foreach (Guid id in ids)
{
    // Get a proxy to the persisted workflow instance.
    SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(connectionString);
    WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(id, store);

    // If desired, you can inspect the WorkflowIdentity of the instance
    // using the DefinitionIdentity property to determine whether to apply
    // the update.
    Console.WriteLine(instance.DefinitionIdentity);

    // Create a workflow application. You must specify the updated workflow definition, and
    // you may provide an updated WorkflowIdentity if desired to reflect the update.
    WorkflowIdentity identity = new WorkflowIdentity
    {
        Name = "MortgageWorkflow v1.1",
        Version = new Version(1, 1, 0, 0)
    };

    // Load the persisted workflow instance using the updated workflow definition
    // and with an updated WorkflowIdentity. In this example the MortgageWorkflow class
    // contains the updated definition.
    WorkflowApplication wfApp = new WorkflowApplication(new MortgageWorkflow(), identity);

    // Apply the dynamic update on the loaded instance.
    wfApp.Load(instance, map);

    // Unload the updated instance.
    wfApp.Unload();
}

Reprendre une instance de flux de travail mise à jour

Une fois la mise à jour dynamique appliquée, l’instance de workflow peut être reprise. Notez que la nouvelle définition mise à jour doit WorkflowIdentity être utilisée.

Dans l’exemple suivant, le MortgageWorkflow_v1.1.xaml flux de travail de l’exemple précédent a été compilé et est chargé et repris à l’aide de la définition de flux de travail mise à jour.

// Load the persisted workflow instance using the updated workflow definition
// and updated WorkflowIdentity.
WorkflowIdentity identity = new WorkflowIdentity
{
    Name = "MortgageWorkflow v1.1",
    Version = new Version(1, 1, 0, 0)
};

WorkflowApplication wfApp = new WorkflowApplication(new MortgageWorkflow(), identity);

// Configure persistence and desired workflow event handlers.
// (Omitted for brevity.)
ConfigureWorkflowApplication(wfApp);

// Load the persisted workflow instance.
wfApp.Load(InstanceId);

// Resume the workflow.
// wfApp.ResumeBookmark(...);