Artikel ini dengan cepat merinci langkah -langkah yang perlu Anda lakukan untuk mengaktifkan dukungan untuk Windows Workflow Foundation (WF) di ASP.NET (klasik atau MVC). Mari kita gunakan aplikasi demo yang sangat kecil untuk menunjukkan kepada Anda bagaimana Anda bisa melakukan ini.
Mengintegrasikan WF di ASP.NET adalah sesuatu yang harus saya lakukan dalam beberapa proyek terakhir yang saya kerjakan. Jadi saya pikir saya akan membuat aplikasi sampel kecil yang menunjukkan kepada Anda minimum kode yang diperlukan untuk mencapai ini. Mari Bangun Aplikasi Sampel Langkah demi Langkah ...
Komentar : Artikel ini bukan primer di WF. Diperlukan beberapa pemahaman dasar tentang WF.
Start up SQL Server Management Studio dan buat database baru yang disebut "Workflow". Anda perlu membuat beberapa tabel dan logika (prosedur tersimpan dan semacamnya) untuk mendukung kegigihan untuk WF. Di direktori "C: Windows Microsoft.net Framework V3.0 Windows Workflow Foundation Sql en" Anda akan menemukan 4 file sql. Jalankan dua berikut dalam urutan ini:
Ini membuat dua tabel dan 10 prosedur tersimpan yang diperlukan untuk mendukung kegigihan untuk WF dalam database SQL Server. Sekarang unduh kode sumber untuk artikel ini, ekstrak dan jalankan skrip DDL.SQL. Skrip ini membuat satu tabel yang disebut pelanggan.
Anda harus berakhir dengan struktur basis data yang terlihat seperti ini:
Gambar 1 - Basis Data Alur Kerja

Saat Anda membuka solusi sampel artikel ini, Anda akan menemukan satu proyek perpustakaan kode yang disebut "Database". Yang dikandungnya hanyalah file LINQ ke SQL Class yang berisi satu entitas, yaitu pelanggan.
Gambar 2 - Entitas Pelanggan

Aplikasi sampel memungkinkan Anda untuk membuat pelanggan. Yang harus Anda lakukan adalah memasukkan nama pengguna. Setelah itu alur kerja baru dimulai dan Anda dapat memilih untuk menyetujui pelanggan, menolaknya atau tidak melakukan apa -apa. Jika Anda tidak mengambil tindakan, pelanggan akan dihapus setelah batas waktu tertentu.
Gambar 3 - Alur kerja

Dalam sampel ini ada satu alur kerja mesin negara. Untuk alur kerja seperti itu, Anda harus memberikan keadaan awal dan lengkap. Seperti yang dapat Anda lihat pada gambar di atasnya hanya berisi dua negara yang dinamai dengan tepat.
Alur kerja ini membutuhkan satu parameter yang disebut nama pengguna. Ketika tiba dalam keadaan awal, stateInitializationActivity dieksekusi dan pelanggan baru dibuat dan bertahan dalam tabel pelanggan. Secara default semua pelanggan memerlukan persetujuan.
Gambar 4 - Pelanggan menunggu persetujuan

Saya telah menempatkan alur kerja ini dalam proyek terpisah.
Gambar 5 - Solusinya

Ketika stateInitializationActivity telah selesai mengeksekusi alur kerja akan mendengarkan salah satu dari 3 acara yang mungkin:
Acara timeout bergantung pada keterlambatan. Anda sendiri tidak harus memecat acara ini, namun Anda bertugas menembakkan dua acara lainnya. Karenanya saya membuat layanan lokal.
Daftar 1 - Antarmuka IcustomerService
[ ExternalDataExchange ]
public interface ICustomerService
{
event EventHandler < ExternalDataEventArgs > Approved ;
event EventHandler < ExternalDataEventArgs > Rejected ;
}Anda hanya dapat mendaftarkan satu implementasi untuk layanan lokal di runtime alur kerja dan implementasi untuk layanan pelanggan terlihat seperti ini:
Daftar 2 - Layanan Pelanggan
public class CustomerService : ICustomerService
{
public event EventHandler < ExternalDataEventArgs > Approved ;
public event EventHandler < ExternalDataEventArgs > Rejected ;
private bool FireEvent ( EventHandler < ExternalDataEventArgs > theEvent , ExternalDataEventArgs args )
{ //...}
public bool OnApproved ( Guid instanceId )
{
return FireEvent ( Approved , new ExternalDataEventArgs ( instanceId ) ) ;
}
public bool OnRejected ( Guid instanceId )
{
return FireEvent ( Rejected , new ExternalDataEventArgs ( instanceId ) ) ;
}
}Layanan lokal ini memungkinkan Anda untuk memicu acara yang disetujui atau ditolak dengan menentukan ID instance (GUID) dari alur kerja yang ingin Anda terus dieksekusi.
Tidak ada banyak logika yang terlibat dalam menciptakan, menyetujui, atau menolak pelanggan tetapi saya telah memasukkan semua ini di kelas pelanggan. Metode ini jelas. Kelas ini memungkinkan Anda untuk mengambil daftar semua pelanggan, menambahkan pelanggan baru, menyetujui, menolak dan menghapus pelanggan.
Daftar 3 - Kelas CustomerManager
public class CustomerManager
{
public IEnumerable < Customer > GetCustomers ( ) { //... }
public Customer GetCustomerById ( Guid customerId ) { //... }
public void ApproveCustomer ( Guid customerId ) { //... }
public void RejectCustomer ( Guid customerId ) { //... }
public void DeleteCustomer ( Guid customerId ) { //... }
public void AddCustomer ( Guid customerId , string userName ) { //... }
}Alur kerja menggunakan tipe pelanggan pelanggan ini untuk melakukan semua pekerjaannya.
Voila, fondasinya diletakkan. Anda telah mengatur database yang mendukung kegigihan WF, menciptakan alur kerja untuk membuat, menyetujui, dan menolak pelanggan dan membuat layanan lokal yang akan membantu Anda mengarahkan instance alur kerja Anda apa yang harus dilakukan.
Sekarang mari kita buat aplikasi web ASP.NET baru yang akan membuat semua ini berfungsi. Saya telah menemukan nama asli "WebApplication" untuk proyek ASP.NET.
Gambar 6 - Proyek Aplikasi Web

Situs ini hanya berisi satu halaman yang disebut default.aspx. Halaman ini menampilkan daftar pelanggan, memungkinkan Anda untuk menambahkan pelanggan baru dan menyetujui atau menolak yang sudah ada.
Gambar 7 - halaman default.aspx

Mari kita konfigurasikan aplikasi web sehingga mendukung WF. Kode konfigurasi yang ditampilkan dalam artikel ini disingkat untuk dibaca. Unduh kode sumber sampel untuk versi lengkapnya.
Buka file konfigurasi aplikasi Anda (web.config) dan tambahkan baris berikut ke bagian ConfigSecsion.
< configSections >
<!-- ... -->
< section name = " WorkflowRuntime "
type = " System.Workflow.Runtime.Configuration.WorkflowRuntimeSection...etc. " />
</ configSections >Anda perlu menambahkan baris ini ke node konfigurasi sehingga .net tahu itu harus menggunakan jenis workflowruntimime untuk membaca bit konfigurasi berikut yang perlu Anda tambahkan ke node konfigurasi.
< WorkflowRuntime >
< CommonParameters >
< add name = " ConnectionString " value = " your connection string " />
</ CommonParameters >
< Services >
< add type = " System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService,...etc. "
useActiveTimers = " true " />
< add type = " System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,...etc. "
UnloadOnIdle = " true " LoadIntervalSeconds = " 5 " />
</ Services >
</ WorkflowRuntime >Workflowruntime Node memuat manualWorkFlowsChedulerService dan SQLWorkFlowPersistencesService Services untuk runtime alur kerja. Anda harus memuat SQLWorkFlowPersistencesService jika Anda ingin bertahan dari alur kerja dan untuk ASP.NET disarankan untuk menggunakan ManualWorkFlowsChedulerService alih -alih layanan DefaultWorkFlowsChedulerService.
Setiap instance alur kerja dieksekusi pada utas terpisah. Runtime alur kerja mengelola ini menggunakan layanan penjadwal alur kerja. Secara default runtime menggunakan tipe DefaultWorkFlowsChedulerService. Semua instance alur kerja dieksekusi dengan cara yang tidak sinkron.
Untuk ASP.NET, yang terbaik adalah menggunakan manualworkflowschedulerservice, karena memungkinkan Anda untuk menjalankan alur kerja secara serempak. Runtime alur kerja menggunakan utas panggilan dari aplikasi host dalam kasus ini.
Ini memungkinkan Anda untuk menunggu tanggapan dari alur kerja sebelum ASP.NET mengirimkan tanggapan. Tentu saja tidak bijaksana untuk melaksanakan tugas yang sudah berjalan lama dalam alur kerja Anda dalam kasus ini. (PS: Lihat posting blog ini untuk informasi lebih lanjut tentang topik ini.)
Saat menggunakan ManualWorkFlowsChedulerService, pastikan Anda mengatur properti Useactivetimers ke True. Jika Anda meninggalkan pengaturan ini diatur ke nilai default False maka setiap delayaktifitas tidak akan dilanjutkan secara otomatis setelah mereka kedaluwarsa. Jika diatur ke true, runtime alur kerja akan menggunakan timer dalam memori untuk secara berkala memeriksa aktivitas tertunda yang kadaluwarsa.
Sekarang aplikasi Anda telah dikonfigurasi ke Penggunaan Workflow Foundation, Anda perlu meng -host runtime alur kerja.
Di ASP.NET, tempat yang ideal untuk melakukan ini adalah dalam file global.asax. Cukup tambahkan kode berikut ke penangan acara Application_Start (...).
Listing 4 - Global.asax Application_Start
protected void Application_Start ( object sender , EventArgs e )
{
WorkflowRuntime runtime = new WorkflowRuntime ( "WorkflowRuntime" ) ;
ExternalDataExchangeService exchangeService = new ExternalDataExchangeService ( ) ;
runtime . AddService ( exchangeService ) ;
CustomerService customerService = new CustomerService ( ) ;
exchangeService . AddService ( customerService ) ;
runtime . StartRuntime ( ) ;
Application [ "WorkflowRuntime" ] = runtime ;
}Contoh baru dari workflowruntime dibuat, maka ExternalDataExchangeservice dibuat dan ditambahkan ke runtime. Selanjutnya kami membuat instance dari layanan lokal IcustomerService kami dan menambahkannya ke instance ExternalDataExchangeService. Akhirnya runtime dimulai dan disimpan dalam keadaan aplikasi.
Demikian juga Anda perlu menghentikan runtime alur kerja saat aplikasi berakhir seperti yang ditunjukkan pada Listing 5.
Listing 5 - Global.asax Application_end
protected void Application_End ( object sender , EventArgs e )
{
WorkflowRuntime runtime = Application [ "WorkflowRuntime" ] as WorkflowRuntime ;
if ( runtime != null )
{
runtime . StopRuntime ( ) ;
runtime . Dispose ( ) ;
}
} Saat Anda mengklik tombol Tambah, Anda harus memulai alur kerja baru. Saat menggunakan ManualWorkFlowsChedulerService, Anda berada dalam kendali penuh menjalankan instance alur kerja Anda. Dalam Listing 6 Anda dapat melihat bahwa Anda perlu mengikuti langkah -langkah ini:
Listing 6 - Buat Pelanggan Baru
WorkflowRuntime runtime = ( WorkflowRuntime ) Application [ "WorkflowRuntime" ] ;
Dictionary < string , object > arguments = new Dictionary < string , object > ( ) ;
arguments . Add ( "UserName" , txtUserName . Text . Trim ( ) ) ;
WorkflowInstance workflow = runtime . CreateWorkflow ( typeof ( CustomerApprovalWorkflow ) , arguments ) ;
workflow . Start ( ) ;
ManualWorkflowSchedulerService scheduler =
( ManualWorkflowSchedulerService ) runtime . GetService ( typeof ( ManualWorkflowSchedulerService ) ) ;
scheduler . RunWorkflow ( workflow . InstanceId ) ; Setelah Anda membuat pelanggan, Anda dapat menyetujui atau menolak akunnya. Dengan kata lain Anda perlu melanjutkan alur kerja yang dimulai ketika Anda membuat akunnya.
Kode yang ditampilkan dalam Listing 7 mirip dengan Listing 6. Satu -satunya perbedaan adalah Anda harus mengambil contoh layanan lokal Anda (layanan pelanggan) dan menyebutnya metode yang disetujui (...). Metode yang disetujui memicu acara yang disetujui. Setelah pengiriman yang berhasil, Anda dapat menginstruksikan penjadwal untuk terus menjalankan alur kerja.
Listing 7 - Menyetujui pelanggan
WorkflowRuntime runtime = ( WorkflowRuntime ) Application [ "WorkflowRuntime" ] ;
ManualWorkflowSchedulerService scheduler =
( ManualWorkflowSchedulerService ) runtime . GetService ( typeof ( ManualWorkflowSchedulerService ) ) ;
CustomerService customerService = ( CustomerService ) runtime . GetService < ICustomerService > ( ) ;
if ( customerService . OnApproved ( customerId ) )
{
scheduler . RunWorkflow ( customerId ) ;
}Menolak akun pelanggan serupa. Anda hanya perlu mengirim acara yang ditolak alih -alih acara yang disetujui. Jika Anda tidak mengambil tindakan maka keterlambatan akan dipicu setelah satu menit dan akun pelanggan akan secara otomatis dihapus.
Dan hanya itu yang ada di sana.