동적 업데이트는 워크플로 애플리케이션 개발자가 지속형 워크플로 인스턴스의 워크플로 정의를 업데이트하는 메커니즘을 제공합니다. 이는 버그 수정, 새 요구 사항을 구현하거나 예기치 않은 변경 내용을 수용하기 위한 것입니다. 이 항목에서는 .NET Framework 4.5에 도입된 동적 업데이트 기능에 대한 개요를 제공합니다.
지속형 워크플로 인스턴스에 동적 업데이트를 적용하기 위해 지속형 워크플로 인스턴스 DynamicUpdateMap 를 수정하여 원하는 변경 내용을 반영하는 방법을 설명하는 런타임에 대한 지침이 포함된 동적 업데이트를 만듭니다. 업데이트 맵이 만들어지면 원하는 지속형 워크플로 인스턴스에 적용됩니다. 동적 업데이트가 적용되면 새로 업데이트된 워크플로 정의를 사용하여 워크플로 인스턴스를 다시 시작합니다. 업데이트 맵을 만들고 적용하는 데는 4단계가 필요합니다.
- 동적 업데이트에 대한 워크플로 정의를 준비합니다.
- 원하는 변경 내용을 반영하도록 워크플로 정의를 업데이트합니다.
- 업데이트 맵을 만듭니다.
- 원하는 지속형 워크플로 인스턴스에 업데이트 맵을 적용합니다.
비고
업데이트 맵 만들기를 다루는 1~3단계는 업데이트 적용과는 별도로 수행할 수 있습니다. 일반적인 시나리오는 워크플로 개발자가 오프라인으로 업데이트 맵을 만든 다음 관리자가 나중에 업데이트를 적용하는 것입니다.
이 문서에서는 컴파일된 Xaml 워크플로의 지속형 인스턴스에 새 활동을 추가하는 동적 업데이트 프로세스의 개요를 제공합니다.
동적 업데이트를 위한 워크플로 정의 준비
동적 업데이트 프로세스의 첫 번째 단계는 업데이트에 필요한 워크플로 정의를 준비하는 것입니다. 이 작업은 메서드를 DynamicUpdateServices.PrepareForUpdate 호출하고 수정할 워크플로 정의를 전달하여 수행됩니다. 이 메서드는 나중에 수정된 워크플로 정의와 비교할 수 있도록 태그를 지정해야 하는 공용 활동 및 변수와 같은 모든 개체를 식별하기 위해 워크플로 트리의 유효성을 검사한 다음 안내합니다. 이 작업이 완료되면 워크플로 트리가 복제되고 원래 워크플로 정의에 연결됩니다. 업데이트 맵이 만들어지면 워크플로 정의의 업데이트된 버전이 원래 워크플로 정의와 비교되고 업데이트 맵은 차이점에 따라 생성됩니다.
동적 업데이트를 위해 Xaml 워크플로를 준비하려면, ActivityBuilder에 로드한 후, ActivityBuilder를 DynamicUpdateServices.PrepareForUpdate에 전달할 수 있습니다.
비고
직렬화된 워크플로 ActivityBuilder를 사용하는 방법에 대한 자세한 내용은 XAML을 오가는 워크플로 및 활동 직렬화를 참조하세요.
다음 예에서는 여러 자식 활동으로 구성된 MortgageWorkflow
정의가 Sequence로 로드되어, 다음에 있을 동적 업데이트를 준비합니다. 메서드가 반환된 후, ActivityBuilder에는 원본 워크플로 정의와 그 복사본이 포함됩니다.
// 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);
원하는 변경 내용을 반영하도록 워크플로 정의 업데이트
워크플로 정의를 업데이트할 준비가 되면 원하는 변경을 수행할 수 있습니다. 활동을 추가 또는 제거하고, 공용 변수를 추가, 이동 또는 삭제하고, 인수를 추가 또는 제거하고, 활동 대리자의 서명을 변경할 수 있습니다. 실행 중인 활동을 제거하거나 실행 중인 대리자의 서명을 변경할 수 없습니다. 이러한 변경 내용은 코드를 사용하거나 다시 호스팅된 워크플로 디자이너에서 만들 수 있습니다. 다음 예제에서는 이전 예제의 VerifyAppraisal
본문을 구성하는 시퀀스에 사용자 지정 MortgageWorkflow
작업이 추가됩니다.
// 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);
업데이트 맵 만들기
업데이트에 대해 준비된 워크플로 정의가 수정되면 업데이트 맵을 만들 수 있습니다. 동적 업데이트 맵을 만들기 위해 메서드가 DynamicUpdateServices.CreateUpdateMap 호출됩니다. 이렇게 하면 런타임에서 새 워크플로 정의로 로드하고 다시 시작할 수 있도록 지속된 워크플로 인스턴스를 수정하는 데 필요한 정보를 포함하는 DynamicUpdateMap를 반환합니다. 다음 예제에서는 이전 예제에서 수정된 MortgageWorkflow
정의에 대한 동적 맵을 만듭니다.
// Create the update map.
DynamicUpdateMap map = DynamicUpdateServices.CreateUpdateMap(ab);
이 업데이트 맵을 즉시 사용하여 지속형 워크플로 인스턴스를 수정하거나, 일반적으로 저장하고 나중에 업데이트를 적용할 수 있습니다. 업데이트 맵을 저장하는 한 가지 방법은 다음 예제와 같이 파일로 serialize하는 것입니다.
// 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);
}
반환되면 DynamicUpdateServices.CreateUpdateMap 호출 DynamicUpdateServices.PrepareForUpdate 에 추가된 복제된 워크플로 정의 및 기타 동적 업데이트 정보가 제거되고 수정된 워크플로 정의는 나중에 업데이트된 워크플로 인스턴스를 다시 시작할 때 사용할 수 있도록 저장할 준비가 됩니다. 다음 예제에서는 수정된 워크플로 정의가 .에 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();
원하는 지속형 워크플로 인스턴스에 업데이트 맵 적용
업데이트 맵을 만든 후 언제든지 업데이트 맵을 적용할 수 있습니다. 반환된 DynamicUpdateMap인스턴스를 DynamicUpdateServices.CreateUpdateMap 사용하여 즉시 수행하거나 나중에 업데이트 맵의 저장된 복사본을 사용하여 수행할 수 있습니다. 워크플로 인스턴스를 업데이트하려면 WorkflowApplicationInstance에 인스턴스를 WorkflowApplication.GetInstance을 사용하여 로드합니다. 다음으로 업데이트된 워크플로 정의와 원하는 WorkflowApplication을 사용하여 WorkflowIdentity을 만듭니다. 이는 WorkflowIdentity 원래 워크플로를 유지하는 데 사용된 것과 다를 수 있으며 일반적으로 지속형 인스턴스가 수정되었음을 반영하기 위한 것입니다. WorkflowApplication이(가) 만들어진 후, WorkflowApplication.Load를 사용하는 DynamicUpdateMap의 오버로드를 통해 로드된 다음, WorkflowApplication.Unload 호출을 통해 언로드됩니다. 동적 업데이트를 적용하고 업데이트된 워크플로 인스턴스를 유지합니다.
// 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();
}
업데이트된 워크플로 인스턴스 다시 시작
동적 업데이트가 적용되면 워크플로 인스턴스가 다시 시작될 수 있습니다. 새롭게 업데이트된 정의와 WorkflowIdentity를 반드시 사용해야 합니다.
비고
WorkflowApplication 및 WorkflowIdentity 사용에 대한 자세한 내용은 WorkflowIdentity 및 버전 지정 사용하기를 참조하세요.
다음 예제에서는 이전 예제의 MortgageWorkflow_v1.1.xaml
워크플로가 컴파일되었으며 업데이트된 워크플로 정의를 사용하여 로드되고 다시 시작됩니다.
// 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(...);
.NET