Aktualizacja dynamiczna
Aktualizacja dynamiczna udostępnia mechanizm dla deweloperów aplikacji przepływu pracy w celu zaktualizowania definicji przepływu pracy utrwalonego wystąpienia przepływu pracy. Może to być implementacja poprawki błędów, nowych wymagań lub uwzględnienia nieoczekiwanych zmian. Ten temat zawiera omówienie funkcji aktualizacji dynamicznej wprowadzonej w programie .NET Framework 4.5.
Aktualizacja dynamiczna
Aby zastosować aktualizacje dynamiczne do utrwalonego wystąpienia przepływu pracy, DynamicUpdateMap tworzony jest obiekt zawierający instrukcje dotyczące środowiska uruchomieniowego opisujące sposób modyfikowania utrwalonego wystąpienia przepływu pracy w celu odzwierciedlenia żądanych zmian. Po utworzeniu mapy aktualizacji zostanie ona zastosowana do żądanych trwałych wystąpień przepływu pracy. Po zastosowaniu aktualizacji dynamicznej wystąpienie przepływu pracy może zostać wznowione przy użyciu nowej zaktualizowanej definicji przepływu pracy. Istnieją cztery kroki wymagane do utworzenia i zastosowania mapy aktualizacji.
Przygotowywanie definicji przepływu pracy do aktualizacji dynamicznej
Aktualizowanie definicji przepływu pracy w celu odzwierciedlenia żądanych zmian
Stosowanie mapy aktualizacji do żądanych wystąpień utrwalonego przepływu pracy
Uwaga
Należy pamiętać, że kroki od 1 do 3, które obejmują tworzenie mapy aktualizacji, mogą być wykonywane niezależnie od stosowania aktualizacji. Typowy scenariusz, w przypadku którego deweloper przepływu pracy utworzy mapę aktualizacji w trybie offline, a następnie administrator zastosuje aktualizację w późniejszym czasie.
Ten temat zawiera omówienie procesu aktualizacji dynamicznej dodawania nowego działania do utrwalonego wystąpienia skompilowanego przepływu pracy Xaml.
Przygotowywanie definicji przepływu pracy do aktualizacji dynamicznej
Pierwszym krokiem procesu aktualizacji dynamicznej jest przygotowanie żądanej definicji przepływu pracy do aktualizacji. Odbywa się to przez wywołanie DynamicUpdateServices.PrepareForUpdate metody i przekazanie definicji przepływu pracy w celu zmodyfikowania. Ta metoda sprawdza poprawność, a następnie przeprowadzi drzewo przepływu pracy, aby zidentyfikować wszystkie obiekty, takie jak działania publiczne i zmienne, które należy oznaczyć, aby można je było porównać później z zmodyfikowaną definicją przepływu pracy. Po zakończeniu drzewo przepływu pracy zostanie sklonowane i dołączone do oryginalnej definicji przepływu pracy. Po utworzeniu mapy aktualizacji zaktualizowana wersja definicji przepływu pracy jest porównywana z oryginalną definicją przepływu pracy, a mapa aktualizacji jest generowana na podstawie różnic.
Aby przygotować przepływ pracy Xaml na potrzeby aktualizacji dynamicznej, może zostać załadowany do ActivityBuilderelementu , a następnie ActivityBuilder przekazany do DynamicUpdateServices.PrepareForUpdateelementu .
Uwaga
Aby uzyskać więcej informacji na temat pracy z serializowanymi przepływami pracy i ActivityBuilder, zobacz Serializowanie przepływów pracy i działań do i z XAML.
W poniższym przykładzie MortgageWorkflow
definicja (składająca się z Sequence kilku działań podrzędnych) jest ładowana do ActivityBuilderelementu , a następnie przygotowana do aktualizacji dynamicznej. Po powrocie metody element ActivityBuilder zawiera oryginalną definicję przepływu pracy oraz kopię.
// 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);
Aktualizowanie definicji przepływu pracy w celu odzwierciedlenia żądanych zmian
Po przygotowaniu definicji przepływu pracy do aktualizacji można wprowadzić odpowiednie zmiany. Możesz dodawać lub usuwać działania, dodawać, przenosić lub usuwać zmienne publiczne, dodawać lub usuwać argumenty oraz wprowadzać zmiany w podpisie delegatów działań. Nie można usunąć uruchomionego działania ani zmienić podpisu uruchomionego delegata. Te zmiany mogą zostać wprowadzone przy użyciu kodu lub w projektancie przepływu pracy hostowanego ponownie. W poniższym przykładzie do sekwencji jest dodawane działanie niestandardowe VerifyAppraisal
, które składa się na treść MortgageWorkflow
z poprzedniego przykładu.
// 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);
Tworzenie mapy aktualizacji
Po zmodyfikowaniu definicji przepływu pracy przygotowanej do aktualizacji można utworzyć mapę aktualizacji. Aby utworzyć mapę aktualizacji dynamicznej, wywoływana DynamicUpdateServices.CreateUpdateMap jest metoda . Spowoduje to zwrócenie elementu DynamicUpdateMap zawierającego informacje, które środowisko uruchomieniowe musi zmodyfikować utrwalone wystąpienie przepływu pracy, aby mogło zostać załadowane i wznowione przy użyciu nowej definicji przepływu pracy. W poniższym przykładzie zostanie utworzona mapa dynamiczna dla zmodyfikowanej MortgageWorkflow
definicji z poprzedniego przykładu.
// Create the update map.
DynamicUpdateMap map = DynamicUpdateServices.CreateUpdateMap(ab);
Ta mapa aktualizacji może być natychmiast używana do modyfikowania utrwalonego wystąpienia przepływu pracy lub zazwyczaj można je zapisać, a aktualizacje zastosowane później. Jednym ze sposobów zapisania mapy aktualizacji jest serializowanie jej do pliku, jak pokazano w poniższym przykładzie.
// 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);
}
Po DynamicUpdateServices.CreateUpdateMap powrocie sklonowana definicja przepływu pracy i inne informacje o aktualizacji dynamicznej, które zostały dodane w wywołaniu metody DynamicUpdateServices.PrepareForUpdate , zostanie usunięta, a zmodyfikowana definicja przepływu pracy będzie gotowa do zapisania, aby można było jej użyć później podczas wznawiania zaktualizowanych wystąpień przepływu pracy. W poniższym przykładzie zmodyfikowana definicja przepływu pracy jest zapisywana w pliku 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();
Stosowanie mapy aktualizacji do żądanych wystąpień utrwalonego przepływu pracy
Zastosowanie mapy aktualizacji można wykonać w dowolnym momencie po jego utworzeniu. Można to zrobić od razu przy użyciu DynamicUpdateMap wystąpienia, które zostało zwrócone przez DynamicUpdateServices.CreateUpdateMap, lub można to zrobić później przy użyciu zapisanej kopii mapy aktualizacji. Aby zaktualizować wystąpienie przepływu pracy, załaduj WorkflowApplicationInstance je do obiektu przy użyciu polecenia WorkflowApplication.GetInstance. Następnie utwórz WorkflowApplication obiekt przy użyciu zaktualizowanej definicji przepływu pracy i żądanego elementu WorkflowIdentity. Może to WorkflowIdentity być inne niż to, które zostało użyte do utrwalania oryginalnego przepływu pracy, i zazwyczaj jest w celu odzwierciedlenia modyfikacji utrwalonego wystąpienia. Po utworzeniu WorkflowApplication obiektu jest ładowany przy użyciu przeciążenia , które pobiera DynamicUpdateMapelement WorkflowApplication.Load , a następnie jest zwalniane z wywołaniem metody .WorkflowApplication.Unload Dotyczy to aktualizacji dynamicznej i utrwala zaktualizowane wystąpienie przepływu pracy.
// 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();
}
Wznawianie zaktualizowanego wystąpienia przepływu pracy
Po zastosowaniu aktualizacji dynamicznej wystąpienie przepływu pracy może zostać wznowione. Należy pamiętać, że nowa zaktualizowana definicja i WorkflowIdentity musi być używana.
Uwaga
Aby uzyskać więcej informacji na temat pracy z elementami WorkflowApplication i WorkflowIdentity, zobacz Using WorkflowIdentity and Versioning (Używanie identyfikatorów przepływu pracy i przechowywania wersji).
W poniższym przykładzie przepływ pracy z poprzedniego przykładu MortgageWorkflow_v1.1.xaml
został skompilowany i załadowany i wznowiony przy użyciu zaktualizowanej definicji przepływu pracy.
// 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(...);