В этом разделе мы настроим клиент и хост для рабочего процесса типа конечного автомата. Помните, что эти два элемента концептуально различны и могут быть физически разделены. Мы просто комбинируем их для того, чтобы протестировать рабочий процесс и сосредоточиться на его концепциях (а не на концепциях клиентского приложения или сервиса Windows).
Вот шаги для создания кода приложения клиента/хоста:
1. Откройте файл Module 1 .vb, в котором содержится консольное приложение.
2. Вам нужно описать параметры, которые будут передаваться в рабочий процесс. Сначала добавьте два локальных поля на уровне класса для этих значений:
Shared _userld As String Shared _expenseReportId As Guid
В верхней части Sub Main добавьте запрос к пользователю для ввода имитатора идентификатора пользователя. Ваш код должен выглядеть следующим образом:
Console.Write("Enter user паше: ")
_userld = Console.ReadLine()
Затем добавьте определение объекта коллекции Dictionary для хранения параметров, которые будут передаваться в рабочий процесс. Добавьте это определение перед созданием экземпляра рабочего процесса. Код должен выглядеть так:
Dim wfParams As New Dictionary(Of String, Object) wfParams.Add("Userid", _userld)
Dim expenseId As Guid = Guid.NewGuid() wfParams.Add("ExpenseReportld", expenseld)
И наконец, измените вызов метода CreateWorkflow, чтобы он принимал эти параметры. Вот код:
1
workflowlnstance = _
workflowRuntime.CreateWorkflow(GetType(ExpenseReport), wfParams)
3. Добавьте консольное сообщение внутри обработчика события OnWorkf lowCompleted: Shared Sub OnWorkflowCompleted(ByVal sender As Object, _
ByVal e As WorkflowCompletedEventArgs)
WaitHandle.Set()
Console.WriteLine("Workflow Completed")
End Sub
4. Теперь вам нужно настроить вызов для утверждения, которое необходимо на стадии представления отчета. Начните с добавления нового класса с именем ManageApproval.vb. Здесь вы реализуете событие утверждения из интерфейса IApproval, созданного ранее. Вам также понадобится метод для того, чтобы утверждение могло произойти.
Этот код должен выглядеть так:
<Serializable()> _
Public Class ManageApproval Implements IApproval
Public Event Approval(ByVal sender As Object, _
ByVal e As ApprovalEventArgs) Implements IApproval.Approval
Public Sub ApproveExpenseReport(ByVal expenseReportld As Guid, _
ByVal isApproved As Boolean, ByVal wflnstanceld As Guid)
Dim appArgs As New ApprovalEventArgs(wflnstanceld) appArgs.IsApproved = isApproved RaiseEvent Approval(Me, appArgs)
End Sub End Class
5. Откройте Module l.vb и сразу под WorkflowRuntime создайте новый экземпляр класса ManageApproval и зарегистрируйте его в исполняющей среде рабочих процессов следующим образом:
Создать объект обмена данными
Dim exchangeServ As New ExternalDataExchangeService() workflowRuntime.AddService(exchangeServ)
' Настроить обмен HandleExternalEvent Dim approvalMgr As New ManageApproval() exchangeServ.AddService(approvalMgr)
6. Теперь вам нужно обработать утверждение (в зависимости от ввода пользователя). Добавьте для этого в Module l.vb следующий код (под вызовом
workf lowinstance. Statt):
' Ждать запуска рабочим процессом события уведомления Thread.Sleep(300)
' Получить утверждение
Console.Write("Enter 'approve' to approve, or anything else to reject: ")
Dim approval As String = Console.ReadLine()
If approval = "approve" Then
approvalMgr.ApproveExpenseReport(expenseld, True, _ workflowinstance.Instanceld)
Else
approvalMgr.ApproveExpenseReport(expenseld, False,
workflowinstance.Instanceld)
End If
7. Теперь нам нужно выполнить аналогичный набор шагов для регистрации уведомления финансового отдела об оплате. Начнем с создания нового файла ManagePayment.vb. В этом классе реализуем интерфейс IPaymentNotice:
<Serializable()> _
Public Class ManagePayment Implements IPaymentNotice
Public Event Approval(ByVal sender As Object, _
ByVal e As PaymentNoticeEventArgs) Implements* IPaymentNotice.Approval
Public Sub ProcessPayment(ByVal expenseReportld As Guid, _
ByVal checkNumber As Integer, ByVal wflnstanceld As Guid)
Dim payArgs As New PaymentNoticeEventArgs(wflnstanceld) payArgs.CheckNumber = checkNumber RaiseEvent Approval(Me, payArgs)
End Sub End Class
8. Вернитесь к Module l.vb и зарегистрируйте экземпляр этого нового класса в исполняющей среде следующим образом:
Dim paymentMgr As New ManagePayment() exchangeServ.AddService(paymentMgr)
9. Внутри утвержденной области блока If. . .Else консольного приложения добавьте запрос для имитации ввода финансовым отделом номера чека (листинг 20.2).
10. Полный код хоста и клиента показан в листинге 20.2.
Module Module1 Class Program
Shared WaitHandle As New AutoResetEvent(False) Shared _userld As String Shared _expenseReportId As Guid
Shared Sub Main()
Using workflowRuntime As New WorkflowRuntime() AddHandler workflowRuntime.WorkflowCompleted,
AddressOf OnWorkflowCompleted
AddHandler workflowRuntime.WorkflowTerminated, _
AddressOf OnWorkflowTerminated
' Создать объект обмена данными
Dim exchangeServ As New ExternalDataExchangeService() workflowRuntime.AddService(exchangeServ)
' Настроить обмен HandleExternalEvent Dim approvalMgr As New ManageApproval() exchangeServ.AddService(approvalMgr)
Dim paymentMgr As New ManagePayment () exchangeServ.AddService(paymentMgr)
Console.Write("Enter user name: ")
_userld = Console.ReadLine()
Dim wfParams As New Dictionary(Of String, Object) wfParams.Add("Userid", _userld)
Dim expenseld As Guid = Guid.NewGuid() wfParams.Add("ExpenseReportld", expenseld)
Dim workflowlnstance As Workflowlnstance workflowlnstance = workflowRuntime.CreateWorkflow( _
GetType(ExpenseReport), wfParams)
workflowlnstance.Start()
Console.WriteLine("Workflow Started: " + _
workflowlnstance.Instanceld.ToString())
' Ждать запуска рабочим процессом события уведомления Thread.Sleep(300)
' Получить утверждение Console.Write( _
"Enter 'approve' to approve, or anything else to reject: ") Dim approval As String = Console.ReadLine()
If approval = "approve" Then
approvalMgr.ApproveExpenseReport(expenseld, True, _
workflowlnstance.Instanceld)
' Ждать уведомления финансового отдела Thread.Sleep(300)
Console.Write("Enter check number (int): ")
Dim checkNbr As String = Console.ReadLine()
paymentMgr.ProcessPayment(expenseld, Integer.Parse(checkNbr), _
workflowlnstance.Instanceld)
Else
approvalMgr.ApproveExpenseReport(expenseld, False, _
workflowlnstance.Instanceld)
End If
WaitHandle.WaitOne()
Console.WriteLine("")
Console.WriteLine("Hit enter to exit.")
Console.ReadLine()
End Using End Sub
Shared Sub OnWorkflowCompleted(ByVal sender As Object, _
ByVal e As WorkflowCompletedEventArgs)
WaitHandle.Set()
Console.WriteLine("Workflow Completed")
End Sub
Shared Sub OnWorkflowTerminated(ByVal sender As Object, _
ByVal e As WorkflowTerminatedEventArgs)
Console.WriteLine(e.Exception.Message)
WaitHandle.Set()
End Sub