Для примера предположим, что теперь вам нужно обрабатывать авансовые отчеты пользователей по тем поездкам, которые они запрашивали в предыдущем примере. Пользователь будет создавать авансовый отчет и сохранять его как черновик. Когда авансовый отчет будет готов, пользователь представит его менеджеру на утверждение (через клиентское приложение). После этого он поступит в рабочий процесс в состоянии "представлен". Затем менеджер утвердит или отклонит отчет. Если отчет утвержден, то он переходит в состояние "утвержден". Если он отклонен, то рабочий процесс уведомит об этом пользователя и экземпляр рабочего процесса завершится. Позднее пользователь может повторно представить отчет (если это требуется). После утверждения отчета в финансовый отдел будет послано уведомление о необходимости выплаты. После обработки выплаты пользователь будет уведомлен о номере чека выплаты и отчет перейдет в свое финальное состояние — "завершен".
Примечание
В этом разделе мы намеренно сосредоточились на специфичных для конечного автомата элементах. Если вы не можете понять эту концепцию, вернитесь к последовательному примеру и перечитайте в нем все подробности.
Для того чтобы при помощи Visual Studio 2008 создать этот рабочий процесс типа конечного автомата, необходимо выполнить следующие шаги:
1. Создайте новый проект Machine workflow Console application project с именем Ex- penseReportWf (на языке Visual Basic или на С#). В этом примере используется Visual Basic (поскольку в предыдущем был С#). Однако концепция и визуальный дизайн остаются теми же самыми. Мы будем использовать версию консольного приложения для тестирования и выполнения рабочего процесса (без необходимости создания отдельных хоста и клиента).
2. Переименуйте рабочий процесс по умолчанию (Workflowl) в шаблоне проекта в ExpenseReport. По умолчанию Visual Studio создаст рабочий процесс в виде кода. Однако этот пример работает как с кодовым рабочим процессом, так и с рабочим процессом в виде XAML.
3. Когда рабочий процесс Expens eReport создается впервые, ему требуется некоторая информация об авансовом отчете: представляющий его пользователь и идентификатор для привязки к реальному авансовому отчету (через клиентское приложение). Эта информация будет передана как параметры в рабочий процесс из хост-приложения.
Добавьте в рабочий процесс свойства для этих параметров (Userid типа string и ExpenseReportld типа Guid). Ваш код должен выглядеть так:
Private _userld As String Public Property Userid() As String Get
Return _userld End Get
Set(ByVal value As String)
_userld = value End Set End Property
Private _expenseReportId As Guid Public Property ExpenseReportld() As Guid Get
Return _expenseReportId End Get
Set(ByVal value As Guid)
_expenseReportId = value End Set End Property
4. Откройте рабочий поток типа конечного автомата в визуальном конструкторе. Выберите состояние в конструкторе и просмотрите его свойства. Присвойте свойству Name этого состояния значение Submitted.
Это состояние будет представлять те действия, которые происходят при старте рабочего процесса. Поэтому щелкните по этому состоянию правой кнопкой мыши и выберите
пункт Set as Initial State (для того чтобы показать, что это состояние рабочего процесса при старте). Вы должны увидеть слева от состояния зеленую стрелку.
5. Теперь добавьте действия State из панели Toolbox для оставшихся состояний: Approved, Rejected, Paid и Completed. Настройте соответствующим образом их названия. Щелкните правой кнопкой мыши по состоянию Completed и выберите пункт Set as Completed State. Это означает, что данное состояние представляет собой завершение рабочего процесса. На рис. 20.17 показано, как должен выглядеть ваш рабочий процесс.
Инициализация и переход из состояния в состояние
Вспомните, что состояние выполняет определенную последовательность действий, которые приводят к переходу в другие состояния. Для того чтобы это работало, необходимо добавить в состояние действие Statelnitialization или StateFinalization. Первое используется для обработки действий при входе в состояние. Второе применяется (не обязательно) для обработки переходов при выходе из состояния (и до начала следующего состояния).