Delen via


Dynamische update

Dynamische updates bieden ontwikkelaars van werkstroomtoepassingen een mechanisme voor het bijwerken van de werkstroomdefinitie van een persistente werkstroominstantie. Dit kan zijn om een foutoplossing, nieuwe vereisten te implementeren of om onverwachte wijzigingen aan te passen. In dit onderwerp vindt u een overzicht van de functionaliteit voor dynamische updates die is geïntroduceerd in .NET Framework 4.5.

Als u dynamische updates wilt toepassen op een persistent werkstroomexemplaren, wordt er een DynamicUpdateMap gemaakt met instructies voor de runtime waarin wordt beschreven hoe u het persistente werkstroomexemplaren wijzigt om de gewenste wijzigingen weer te geven. Zodra de updatemap is gemaakt, wordt deze toegepast op de gewenste bewaarde workflowinstanties. Zodra de dynamische update is toegepast, kan het werkstroomexemplaar worden hervat met behulp van de bijgewerkte werkstroomdefinitie. Er zijn vier stappen nodig om een updatekaart te maken en toe te passen.

  1. Bereid de werkstroomdefinitie voor op dynamische updates.
  2. Werk de werkstroomdefinitie bij om de gewenste wijzigingen weer te geven.
  3. Maak de updatekaart.
  4. Pas de updatemap toe op de gewenste gepersistente workflowinstanties.

Opmerking

Stappen 1 tot en met 3, die betrekking hebben op het maken van de updatemap, kunnen onafhankelijk van het toepassen van de update worden uitgevoerd. Een veelvoorkomend scenario is dat de workflowontwikkelaar de updatekaart offline maakt, waarna een beheerder de update op een later moment toepast.

Dit artikel bevat een overzicht van het dynamische updateproces van het toevoegen van een nieuwe activiteit aan een persistent exemplaar van een gecompileerde Xaml-werkstroom.

De werkstroomdefinitie voorbereiden voor dynamische updates

De eerste stap in het dynamische updateproces is het voorbereiden van de gewenste werkstroomdefinitie voor update. Dit wordt gedaan door de DynamicUpdateServices.PrepareForUpdate methode aan te roepen en de werkstroomdefinitie door te geven die moet worden gewijzigd. Deze methode valideert en begeleidt vervolgens de werkstroomstructuur om alle objecten te identificeren, zoals openbare activiteiten en variabelen die moeten worden gelabeld, zodat ze later kunnen worden vergeleken met de gewijzigde werkstroomdefinitie. Wanneer dit is voltooid, wordt de werkstroomstructuur gekloond en gekoppeld aan de oorspronkelijke werkstroomdefinitie. Wanneer de updatetoewijzing wordt gemaakt, wordt de bijgewerkte versie van de werkstroomdefinitie vergeleken met de oorspronkelijke werkstroomdefinitie en wordt de updatetoewijzing gegenereerd op basis van de verschillen.

Als u een Xaml-werkstroom wilt voorbereiden voor dynamische updates, kan deze worden geladen in een ActivityBuilder, en vervolgens wordt de ActivityBuilder werkstroom doorgegeven aan DynamicUpdateServices.PrepareForUpdate.

Opmerking

Zie ActivityBuilder voor meer informatie over het werken met geserialiseerde werkstromen.

In het volgende voorbeeld wordt een MortgageWorkflow definitie (die bestaat uit een Sequence met verschillende onderliggende activiteiten) geladen in een ActivityBuilderen vervolgens voorbereid op dynamische updates. Nadat de methode heeft geretourneerd, bevat de ActivityBuilder de oorspronkelijke werkstroomdefinitie en een kopie.

// 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);

Werk de werkstroomdefinitie bij om de gewenste wijzigingen weer te geven

Zodra de werkstroomdefinitie is voorbereid voor het bijwerken, kunnen de gewenste wijzigingen worden aangebracht. U kunt activiteiten toevoegen of verwijderen, openbare variabelen toevoegen, verplaatsen of verwijderen, argumenten toevoegen of verwijderen en wijzigingen aanbrengen in de handtekening van gedelegeerden voor activiteiten. U kunt een actieve activiteit niet verwijderen of de handtekening van een actieve gemachtigde wijzigen. Deze wijzigingen kunnen worden aangebracht met behulp van code of in een opnieuw gehoste werkstroomontwerper. In het volgende voorbeeld wordt een aangepaste VerifyAppraisal activiteit toegevoegd aan de reeks waaruit de hoofdtekst van het MortgageWorkflow vorige voorbeeld bestaat.

// 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);

De updatekaart maken

Zodra de werkstroomdefinitie, die is voorbereid voor bijwerking, is gewijzigd, kan de bijwerkingskaart worden gemaakt. Om een dynamische kaart voor updates te maken, wordt de DynamicUpdateServices.CreateUpdateMap methode aangeroepen. Hiermee wordt een DynamicUpdateMap geretourneerd dat de informatie bevat die de runtime nodig heeft om het persistent werkstroomexemplaar te wijzigen, opdat deze kan worden geladen en hervat met de nieuwe werkstroomdefinitie. In het volgende voorbeeld wordt een dynamische kaart gemaakt voor de gewijzigde MortgageWorkflow definitie uit het vorige voorbeeld.

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

Deze updatekaart kan onmiddellijk worden gebruikt om bewaarde workflow-instanties te wijzigen, of meestal wordt deze opgeslagen en worden de updates later toegepast. Een manier om de updatemap op te slaan, is door deze te serialiseren naar een bestand, zoals wordt weergegeven in het volgende voorbeeld.

// 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);
}

Wanneer DynamicUpdateServices.CreateUpdateMap terugkeert, worden de gekloonde werkstroomdefinitie en andere dynamische updategegevens die zijn toegevoegd bij de oproep naar DynamicUpdateServices.PrepareForUpdate, verwijderd, en is de gewijzigde werkstroomdefinitie klaar om te worden opgeslagen, zodat deze later kan worden gebruikt bij het hervatten van bijgewerkte werkstroomexemplaren. In het volgende voorbeeld wordt de gewijzigde werkstroomdefinitie opgeslagen in 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();

Pas de updatekaart toe op de gewenste persistente werkstroomexemplaren

Het toepassen van de updatekaart kan op elk gewenst moment worden uitgevoerd nadat u deze hebt gemaakt. Het kan direct worden gedaan met behulp van het DynamicUpdateMap exemplaar dat is geretourneerd door DynamicUpdateServices.CreateUpdateMap, of het kan later worden gedaan met behulp van een opgeslagen kopie van de update map. Laad een werkstroomexemplaar in een WorkflowApplicationInstance door WorkflowApplication.GetInstance te gebruiken om het bij te werken. Maak vervolgens een WorkflowApplication met behulp van de bijgewerkte werkstroomdefinitie en de gewenste WorkflowIdentity. Dit WorkflowIdentity kan verschillen van hetgeen dat is gebruikt om de oorspronkelijke werkstroom te bewaren, en is meestal anders om aan te geven dat het bewaarde exemplaar is gewijzigd. Zodra het WorkflowApplication is gemaakt, wordt het geladen met behulp van de overload-methode van WorkflowApplication.Load die een DynamicUpdateMap neemt, en vervolgens verwijderd met een oproep naar WorkflowApplication.Unload. Hiermee wordt de dynamische update toegepast en wordt de bijgewerkte workflow-instantie opgeslagen.

// 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();
}

Een bijgewerkte workflow-instantie hervatten

Zodra dynamische update is toegepast, kan de werkstroominstantie worden hervat. Houd er rekening mee dat de nieuwe bijgewerkte definitie en WorkflowIdentity moet worden gebruikt.

Opmerking

Zie WorkflowApplication gebruiken voor meer informatie over het werken met WorkflowIdentity en.

In het volgende voorbeeld is de MortgageWorkflow_v1.1.xaml werkstroom uit het vorige voorbeeld gecompileerd en geladen en hervat met behulp van de bijgewerkte werkstroomdefinitie.

// 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(...);