Memahami Workflow Foundation
Fyuuh, akhirnya selesai juga membaca buku ke-empat mengenai Workflow Foundation. Empat buku tersebut adalah sebagai berikut :
- Foundations of WF. An Introduction To Windows Workflow Foundation. Dibuat oleh Brian R. Myers. Terbitan Apress.
- Microsoft Windows Workflow Foundation Step by Step. Dibuat oleh Kenn Scribner. Terbitan Microsoft Press.
- Programming Windows Workflow Foundation. Practical WF Techniques and Example using XAML and C#. Dibuat oleh K. Scott Allen. Terbitan PACKT Publishing.
- Professional Windows Workflow Foundation. Dibuat oleh Todd Kita. Terbitan WROX.
Saya coba akan sharing kepada pembaca sekalian seperti apa workflow foundation itu dan bagaimana mengintegrasikannya ke dalam aplikasi. Konsep dasar apa yang harus dipahami agar bisa dengan mudah memahami Workflow Foundation. Dan cukup diingat saja bahwa WF (atau yang lainnya juga seperti AJAX, WCF, ASP .NET) itu semua cuman API saja. Konsep dasarnya ada pada pemahaman mengenai language features, sisi arsitektural, dan paradigma pemrogramannya.
Pengalaman mengisi training Workflow untuk beberapa company adalah berada pada kendala language features pada bahasa C# atau Visual Basic yang rata-rata belum familiar bagi kebanyakan peserta. Anonymous method, interface, delegate, event, event handler, raising event, event arguments, hampir rata-rata peserta semua belum familiar di level sintaks dan implementasi.
Tingkat yang relatif cukup sulit di WF pada kebanyakan peserta adalah mengenai passing data dari Host ke Workflow dan sebaliknya.
Secara umum, komunikasi pada Workflow Foundation terbagi menjadi beberapa alternatif skenario sebagai berikut :
- Host to Workflow and vice versa
- Workflow to Workflow
- Host to Workflow via Custom Business Object and vice versa
- Host to Workflow via Custom Business Object as a workflow service and vice versa
Mengapa saya perlu memberikan pemahaman dasar ini adalah karena ini merupakan pemahaman mendasar yang pertama kali harus dimengerti oleh mereka yang ingin mencoba teknologi WF. Sebab pada dasarnya, WF bukan teknologi yang berdiri sendiri. Ia perlu Host sebagai "induk" tempat melekatkan workflow. Host ini bisa Console, WinForm, WebForm, atau yang lainnya. Oleh karena workflow harus dilekatkan, maka kita perlu memahami model komunikasi dan alternatif kemungkinan yang ada di dalamnya. Dan 4 kemungkinan itulah yang menjadi basic pemahaman awal untuk naik ke level yang lebih tinggi.
Setelah memahami modelnya, kemudian cara komunikasinya juga harus diperhatikan. WF menggunakan model programming based on interface untuk bisa komunikasi dengan eksternal resource workflow. Oleh karena itu konsep interface, abstract class, concrete class, event args, harus sudah familiar. Sebab ini akan menentukan bagaimana cara kita passing data kepadanya.
Contoh mudah, anggaplah ada suatu case dimana kita akan verifikasi suatu dokumen. Kita sudah tentukan bahwa custom business object itu adalah class Document yang terdiri dari DocumentId dan DocumentTitle misalnya. Dan kita akan memanfaatkan model nomor 4 (Host to Workflow via custom business object and vice versa).
So, we have to do like this (dalam pendekatan ala WF) :
1. Buat sebuah custom business object bernama Document dengan property DocumentId dan Title.
using System;
public class Document {
private int documentId;
private string documentTitle;
public int DocumentId {
get { return documentId; }
set { documentId = value; }
}
public string DocumentTitle {
get { return documentTitle; }
set { documentTitle = value; }
}
}
Tidak ada yang aneh pada kelas ini. Cuman single entity yang merepresentasikan object Document. Anda bisa saja membuat kelas yang merupakan kumpulan dari object Document yang diturunkan dari List<Document>. Sehingga tidak perlu lagi menggunakan ArrayList untuk menampungnya. Misal :
using System;
using System.Collections.Generic;
public class Documents : List<Document> {
public Documents() {
}
}
Jadi, nanti Anda tinggal menggunakan pendekatan seperti ini untuk membuat kumpulan dari object Document.
Documents docs = new Documents();
docs.Add(new Document());
2. Buat sebuah kelas EventArgs yang merupakan implementasi object yang nantinya akan dipassing ke workflow --> host atau kebalikannya. Kelas document dibungkus ke dalam eventargs ini. Tandai kelas ini dengan atribut Serializable untuk bisa dipassing antar layer. Jadi nanti kedepannya kelas inilah yang akan "dilempar" antar layer. Di dalamnya kita bisa tambahkan properties dan beberapa proses yang dibutuhkan sesuai dengan skenario business.
using System;
using System.Collections.Generic;
using System.Workflow.Activity;
[Serializable]
public class DocumentEventArgs : ExternalDataEventArgs {
public DocumentEventArgs(Guid instanceId, Document doc) : base(instanceId) {
docSubmit = doc;
}
private Document docSubmit;
public Document DocumentSubmit {
get { return docSubmit; }
set { docSubmit = value; }
}
}
Artinya sekarang kelas DocumentEventArgs merupakan object yang nanti akan kita lewatkan antar layer. Kelas ini juga diturunkan dari kelas ExternalDataEventArgs milik Workflow. Yakni agar nanti si workflow bisa mengenali kelas ini saat akan dipassing antar layer. Object ini karena beris property Document, maka akan dengan mudah mengambil object Document yang dipassing ke dalamnya.
3. Buat interface yang merupakan kontrak apa yang nanti akan dipassing ke workflow
using System;
using System.Collections.Generic;
using System.Workflow.Activity;
[ExternalDataExchange]
public interface IDocument {
void SubmitDocument(Document doc);
event EventHandler<DocumentEventArgs> DocumentSubmitted;
}
Disini interface IDocument di-decorate dengan atribut ExternalDataExchange karena ia adalah interface yang merupakan kontrak antara workflow dengan custom business kita.
4. Buat kelas implementasi dari interface di atas
using System;
using System.Workflow.Activity;
using System.Collections.Generic;
public class DocumentService : IDocument {
public void RaiseDocumentSubmitted(DocumentEventArgs arg) {
event EventHandler<DocumentEventArgs> documentSubmitted = this.DocumentSubmitted;
if (documentSubmitted != null) {
documentSubmitted(null, arg);
}
}
public event EventHandler<DocumentEventArgs> DocumentSubmitted;
public void SubmitDocument(Document doc) {
// do something code here
}
}
5. Register kelas DocumentService itu sebagai service pada host yang ingin workflow tsb kita lekatkan. Misal Console UI apps, winform, atau webform menggunakan pendekatan yang sudah di define oleh WF.
ExternalDataExchangeService dataExchange = new ExternalDataExchangeService();
workflowRuntime.AddService(dataExchange);
DocumentService docService = new DocumentService();
dataExchange.AddService(docService);
Dan sekarang service kita sudah dilekatkan ke dalam workflow engine dan siap digunakan pada workflow activity library yang tersedia.
Lihatlah pendekatan konsepnya. Sebenarnya itu tidak sulit asalkan kita paham level sintaks dan pemahaman arsitektur dasar programming berbasis interface. Konsep inheritance, interface, attribute, event, event handler, raising event, class, concrete class, abstract class, passing data, itu semua ada di level yang non API. Jadi, memahami itu akan membuat pemahaman terhadap WF menjadi lebih mudah.
Nah, rata-rata pendekatan di atas itu jarang atau bahkan belum umum bagi kebanyakan peserta. Bahkan ada yang sama sekali tidak memahami cara kerja event, menggunakan event arguments dan bagaimana mengimplementasikannya ke dalam aplikasi.
Itulah sekelumit singkat pendahuluan yang nanti akan mengiringi artikel lanjutan mengenai workflow ini.
Semoga membantu.