Delen via


Dynamische update

Dynamische update biedt ontwikkelaars van werkstroomtoepassingen een mechanisme voor het bijwerken van de werkstroomdefinitie van een persistent werkstroomexemplaren. 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.

Dynamische update

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 updatetoewijzing is gemaakt, wordt deze toegepast op de gewenste persistente werkstroomexemplaren. Zodra de dynamische update is toegepast, kan het werkstroomexemplaren worden hervat met behulp van de nieuwe bijgewerkte werkstroomdefinitie. Er zijn vier stappen vereist om een updatetoewijzing te maken en toe te passen.

  1. De werkstroomdefinitie voorbereiden voor dynamische updates

  2. Werk de werkstroomdefinitie bij om de gewenste wijzigingen weer te geven

  3. De updatekaart maken

  4. De updatetoewijzing toepassen op de gewenste persistente werkstroomexemplaren

Notitie

Houd er rekening mee dat stap 1 tot en met 3, die betrekking heeft op het maken van de updatetoewijzing, onafhankelijk van het toepassen van de update kan worden uitgevoerd. Een veelvoorkomend scenario dat de werkstroomontwikkelaar de updatetoewijzing offline maakt en vervolgens een beheerder de update op een later tijdstip toepast.

Dit onderwerp 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.

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 is geretourneerd, bevat de ActivityBuilder 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 update is gewijzigd, kan de updatetoewijzing worden gemaakt. Als u een dynamische updatetoewijzing wilt maken, wordt de DynamicUpdateServices.CreateUpdateMap methode aangeroepen. Hiermee wordt een DynamicUpdateMap geretourneerd dat de informatie bevat die de runtime nodig heeft om een persistent werkstroomexemplaren te wijzigen, zodat het 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 updatetoewijzing kan onmiddellijk worden gebruikt om persistente werkstroomexemplaren te wijzigen, of meer meestal kan deze worden opgeslagen en de updates later worden toegepast. Een manier om de updatetoewijzing 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 de werkstroom wordt geretourneerd, worden de gekloonde werkstroomdefinitie en andere dynamische updategegevens die in de aanroep DynamicUpdateServices.PrepareForUpdate zijn toegevoegd, verwijderd en is de gewijzigde werkstroomdefinitie gereed om op te slaan, 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();

De updatetoewijzing toepassen 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 updatetoewijzing. Als u een werkstroomexemplaren wilt bijwerken, laadt u het in een WorkflowApplicationInstance met.WorkflowApplication.GetInstance Maak vervolgens een WorkflowApplication met behulp van de bijgewerkte werkstroomdefinitie en de gewenste WorkflowIdentity. Dit kan anders zijn dan de werkstroom die is gebruikt om de oorspronkelijke werkstroom te behouden. Dit WorkflowIdentity komt meestal overeen met het feit dat het persistente exemplaar is gewijzigd. Zodra het WorkflowApplication is gemaakt, wordt het geladen met behulp van de overbelasting van WorkflowApplication.Load die een DynamicUpdateMap, en vervolgens verwijderd met een aanroep naar WorkflowApplication.Unload. Hiermee wordt de dynamische update toegepast en blijft het bijgewerkte werkstroomexemplaren behouden.

// 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 bijgewerkt werkstroomexemplaren hervatten

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

Notitie

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

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