Pembaruan dinamis

Pembaruan dinamis menyediakan mekanisme bagi pengembang aplikasi alur kerja untuk memperbarui definisi alur kerja dari instans alur kerja yang bertahan. Pembaruan ini bisa untuk menerapkan perbaikan bug, persyaratan baru, atau untuk mengakomodasi perubahan yang tidak terduga. Topik ini memberikan gambaran umum tentang fungsionalitas pembaruan dinamis yang diperkenalkan di .NET Framework 4.5.

Pembaruan dinamis

Untuk menerapkan pembaruan dinamis ke instans alur kerja yang bertahan, DynamicUpdateMap dibuat dengan di dalamnya berisi instruksi untuk runtime bahasa umum yang menjelaskan cara memodifikasi instans alur kerja yang bertahan untuk mencerminkan perubahan yang diinginkan. Setelah peta pembaruan dibuat, peta tersebut diterapkan ke instans alur kerja persisten yang diinginkan. Setelah pembaruan dinamis diterapkan, instans alur kerja dapat dilanjutkan menggunakan definisi alur kerja baru yang diperbarui. Ada empat langkah yang diperlukan untuk membuat dan menerapkan peta pembaruan.

  1. Menyiapkan definisi alur kerja untuk pembaruan dinamis

  2. Memperbarui definisi alur kerja untuk mencerminkan perubahan yang diinginkan

  3. Membuat peta pembaruan

  4. Terapkan peta pembaruan ke instans alur kerja persisten yang diinginkan

Catatan

Perhatikan bahwa langkah 1 hingga 3, yang mencakup pembuatan peta pembaruan, dapat dilakukan secara independen dari menerapkan pembaruan. Skenario umum bahwa pengembang alur kerja akan membuat peta pembaruan secara offline, lalu administrator akan menerapkan pembaruan di lain waktu.

Topik ini memberikan gambaran umum tentang proses pembaruan dinamis menambahkan aktivitas baru ke instans persisten dari alur kerja Xaml yang dikompilasi.

Menyiapkan definisi alur kerja untuk pembaruan dinamis

Langkah pertama dalam proses pembaruan dinamis adalah menyiapkan definisi alur kerja yang diinginkan untuk pembaruan. Langkah ini dilakukan dengan memanggil metode DynamicUpdateServices.PrepareForUpdate dan meneruskan definisi alur kerja untuk memodifikasi. Metode ini memvalidasi dan kemudian memandu pohon alur kerja untuk mengidentifikasi semua objek seperti aktivitas publik dan variabel yang perlu ditandai sehingga dapat dibandingkan nanti dengan definisi alur kerja yang dimodifikasi. Ketika metode ini selesai, pohon alur kerja dikloning dan dilampirkan ke definisi alur kerja asli. Saat peta pembaruan dibuat, versi definisi alur kerja yang diperbarui dibandingkan dengan definisi alur kerja asli dan peta pembaruan dihasilkan berdasarkan perbedaannya.

Untuk menyiapkan alur kerja Xaml untuk pembaruan dinamis, alur kerja dapat dimuat ke dalam ActivityBuilder, dan kemudian ActivityBuilder diteruskan ke DynamicUpdateServices.PrepareForUpdate.

Catatan

Untuk informasi selengkapnya tentang bekerja dengan alur kerja diserialisasi dan ActivityBuilder, lihat Serialisasi Alur Kerja dan Aktivitas ke dan dari XAML.

Dalam contoh berikut, definisi MortgageWorkflow (yang terdiri dari Sequence dengan beberapa aktivitas turunan) dimuat ke dalam ActivityBuilder, dan kemudian disiapkan untuk pembaruan dinamis. Setelah metode kembali, ActivityBuilder berisi definisi alur kerja asli serta salinan.

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

Memperbarui definisi alur kerja untuk mencerminkan perubahan yang diinginkan

Setelah definisi alur kerja disiapkan untuk diperbarui, perubahan yang diinginkan dapat dilakukan. Anda dapat menambahkan atau menghapus aktivitas, menambahkan, memindahkan, atau menghapus variabel publik, menambahkan atau menghapus argumen, dan membuat perubahan pada tanda tangan delegasi aktivitas. Anda tidak dapat menghapus aktivitas yang sedang berjalan atau mengubah tanda tangan delegasi yang sedang berjalan. Perubahan ini dapat dilakukan menggunakan kode, atau dalam perancang alur kerja yang di-hosting ulang. Dalam contoh berikut, aktivitas VerifyAppraisal kustom ditambahkan ke Urutan yang membentuk isi MortgageWorkflow dari contoh sebelumnya.

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

Membuat peta pembaruan

Setelah definisi alur kerja yang disiapkan untuk pembaruan telah dimodifikasi, peta pembaruan dapat dibuat. Untuk membuat peta pembaruan dinamis, metode DynamicUpdateServices.CreateUpdateMap dipanggil. Metode ini mengembalikan DynamicUpdateMap yang berisi informasi yang diperlukan runtime bahasa umum untuk memodifikasi instans alur kerja yang bertahan sehingga dapat dimuat dan dilanjutkan dengan definisi alur kerja baru. Dalam contoh berikut, peta dinamis dibuat untuk definisi MortgageWorkflow yang dimodifikasi dari contoh sebelumnya.

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

Peta pembaruan ini dapat segera digunakan untuk memodifikasi instans alur kerja yang bertahan, atau lebih biasanya dapat disimpan dan pembaruan diterapkan nanti. Salah satu cara untuk menyimpan peta pembaruan adalah dengan menserialisasikannya ke file, seperti yang ditunjukkan dalam contoh berikut.

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

Saat DynamicUpdateServices.CreateUpdateMap kembali, definisi alur kerja kloning dan informasi pembaruan dinamis lainnya yang ditambahkan dalam panggilan ke DynamicUpdateServices.PrepareForUpdate dihapus, dan definisi alur kerja yang dimodifikasi siap disimpan sehingga dapat digunakan nanti saat melanjutkan instans alur kerja yang diperbarui. Dalam contoh berikut, definisi alur kerja yang dimodifikasi disimpan ke 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();

Terapkan peta pembaruan ke instans alur kerja persisten yang diinginkan

Menerapkan peta pembaruan dapat dilakukan kapan saja setelah membuatnya. Membuat peta ini dapat dilakukan langsung dengan menggunakan instans DynamicUpdateMap yang dikembalikan oleh DynamicUpdateServices.CreateUpdateMap, atau dapat dilakukan nanti menggunakan salinan peta pembaruan yang disimpan. Untuk memperbarui instans alur kerja, muat ke dalam WorkflowApplicationInstance menggunakan WorkflowApplication.GetInstance. Selanjutnya, buat WorkflowApplication menggunakan definisi alur kerja yang diperbarui, dan yang diinginkan WorkflowIdentity. WorkflowIdentity ini mungkin berbeda dari yang digunakan untuk mempertahankan alur kerja asli, dan biasanya untuk mencerminkan bahwa instans yang bertahan telah dimodifikasi. Setelah WorkflowApplication dibuat kemudian dimuat menggunakan kelebihan beban WorkflowApplication.Load yang mengambil DynamicUpdateMap, dan kemudian dibongkar dengan panggilan ke WorkflowApplication.Unload. Ini menerapkan pembaruan dinamis dan mempertahankan instans alur kerja yang diperbarui.

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

Melanjutkan Instans Alur Kerja yang Diperbarui

Setelah pembaruan dinamis diterapkan, instans alur kerja dapat dilanjutkan. Perhatikan bahwa definisi baru yang diperbarui dan WorkflowIdentity harus digunakan.

Catatan

Untuk informasi selengkapnya tentang bekerja dengan WorkflowApplication dan WorkflowIdentity, lihat Menggunakan WorkflowIdentity dan Penerapan Versi.

Dalam contoh berikut, alur kerja MortgageWorkflow_v1.1.xaml dari contoh sebelumnya telah dikompilasi, dan dimuat dan dilanjutkan menggunakan definisi alur kerja yang diperbarui.

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