- Новые возможности в Windows Workflow Foundation (WF) What’s New in Windows Workflow Foundation
- Модель действий рабочего процесса Workflow Activity Model
- Параметры сложных композитных действий Rich Composite Activity Options
- Расширенная библиотека встроенных действий Expanded Built-In Activity Library
- Явная модель данных действия Explicit Activity Data Model
- Улучшенные варианты размещения на узле, сохраняемости и отслеживания Enhanced Hosting, Persistence, and Tracking Options
- Более удобное расширение среды проектирования WF Designer Easier Ability to Extend WF Designer Experience
- Windows Workflow Foundation Windows Workflow Foundation
- в этом разделе In This Section
- Workflow Core — движок бизнес-процессов для .Net Core
- Начнем с истории
- Требования
- Windows Workflow Foundation (WWF)
- Workflow Core
- Step (Шаг)
- Описание процесса. Регистрация в движке.
- Json описание процесса
- Регистрация процесса в движке. Публикация события в шину.
- Заключение
Новые возможности в Windows Workflow Foundation (WF) What’s New in Windows Workflow Foundation
Windows Workflow Foundation (WF) в .NET Framework 4 изменяет несколько парадигм разработки из предыдущих версий. Windows Workflow Foundation (WF) in .NET Framework 4 changes several development paradigms from previous versions. Теперь рабочие процессы стало еще проще создавать, выполнять и поддерживать, а также реализовывать узел с новыми функциями. Workflows are now easier to create, execute, and maintain, and implement a host of new functionality. Дополнительные сведения о переносе приложений рабочих процессов .NET Framework 3,0 и .NET Framework 3,5 на использование последней версии см. в руководстве по миграции. For more information about migrating .NET Framework 3.0 and .NET Framework 3.5 workflow applications to use the latest version, see Migration Guidance.
Модель действий рабочего процесса Workflow Activity Model
Теперь действие, а не использования класса SequentialWorkflowActivity или StateMachineWorkflowActivity является базовой единицей создания рабочего процесса. The activity is now the base unit of creating a workflow, rather than using the SequentialWorkflowActivity or StateMachineWorkflowActivity classes. Класс Activity обеспечивает базовую абстракцию поведения рабочего процесса. The Activity class provides the base abstraction of workflow behavior. Авторы действий могут использовать CodeActivity для базовых функций пользовательских действий или NativeActivity для функций пользовательских действий, использующих среду выполнения. Activity authors can then implement either CodeActivity for basic custom activity functionality, or NativeActivity for custom activity functionality that uses the breadth of the runtime. Activity класс, используемый авторами действий для выражения новых поведений декларативно с точки зрения других NativeActivity объектов,, CodeActivity AsyncCodeActivity или DynamicActivity , независимо от того, созданы они или включены в встроенную библиотеку действий. Activity is a class used by activity authors to express new behaviors declaratively in terms of other NativeActivity, CodeActivity, AsyncCodeActivity, or DynamicActivity objects, whether they are custom-developed or included in the Built-In Activity Library.
Параметры сложных композитных действий Rich Composite Activity Options
Flowchart — это новое мощное действие потока управления, позволяющее авторам моделировать произвольные циклы и условное ветвление. Flowchart is a powerful new control flow activity that allows authors to model arbitrary loops and conditional branching. Flowchart предоставляет модель программирования на основе событий, которую раньше можно было реализовать только с помощью StateMachineWorkflowActivity. Flowchart provides an event-driven programming model that was previously only able to be implemented with StateMachineWorkflowActivity. Процедурные рабочие процессы получают дополнительные преимущества благодаря новым действиям управления потоком, которые моделируют обычные структуры управления потоком, такие как TryCatch и Switch . Procedural workflows benefit from new flow-control activities that model traditional flow-control structures, such as TryCatch and Switch .
Расширенная библиотека встроенных действий Expanded Built-In Activity Library
Новые возможности библиотеки действий: New features of the activity library include:
Новые действия управления потоком, такие как DoWhile, Pick, TryCatch, ForEach , Switch и ParallelForEach . New flow control activities, such as, DoWhile, Pick, TryCatch, ForEach , Switch , and ParallelForEach .
Действия для обработки данных элементов, такие как Assign, и действия коллекции, такие как AddToCollection . Activities for manipulating member data, such as Assign and collection activities such as AddToCollection .
Действия для управления транзакциями, такие как TransactionScope и Compensate. Activities for controlling transactions, such as TransactionScope and Compensate.
Новые действия для обмена сообщениями, такие как SendContent и ReceiveReply. New messaging activities such as SendContent and ReceiveReply.
Явная модель данных действия Explicit Activity Data Model
.NET Framework 4 содержит новые варианты хранения или перемещения данных. .NET Framework 4 includes new options for storing or moving data. Данные можно сохранить в действии при помощи переменной Variable. Data can be stored in an activity using Variable. При перемещении данных в действие и из него для определения направления перемещения данных используются специальные типы аргументов. When moving data in and out of an activity, specialized argument types are used to determine which direction data is moving. Такими типами являются InArgument, InOutArgument и OutArgument. These types are InArgument, InOutArgument, and OutArgument. Дополнительные сведения см. в разделе Windows Workflow Foundation Data Model. For more information, see Windows Workflow Foundation Data Model.
Улучшенные варианты размещения на узле, сохраняемости и отслеживания Enhanced Hosting, Persistence, and Tracking Options
.NET Framework 4 содержит следующие усовершенствования сохраняемости: .NET Framework 4 contains persistence enhancements such as the following:
Добавлены новые параметры для выполнения рабочих процессов, включая WorkflowServiceHost, WorkflowApplication и WorkflowInvoker. There are more options for running workflows, including WorkflowServiceHost, WorkflowApplication, and WorkflowInvoker.
При помощи действия Persist данные состояния рабочего процесса можно сохранять явным образом. Workflow state data can be explicitly persisted using the Persist activity.
Узел может сохранить экземпляр ActivityInstance, не выгружая его. A host can persist an ActivityInstance without unloading it.
Рабочий процесс может указывать зоны несохраняемости во время работы с данными, которые не могут быть сохранены, чтобы отложить операцию сохраняемости до выхода из зоны несохраняемости. A workflow can specify no-persist zones while working with data that cannot be persisted, so that persistence is postponed until the no-persist zone exits.
Транзакции могут быть введены в рабочий процесс при помощи TransactionScope. Transactions can be flowed into a workflow using TransactionScope.
Выполнять отслеживание проще благодаря TrackingParticipant. Tracking is more easily accomplished using TrackingParticipant.
Отслеживание и запись в журнал системных событий обеспечивается при помощи EtwTrackingParticipant. Tracking to the system event log is provided using EtwTrackingParticipant.
Для возобновления ожидающего рабочего процесса теперь используется объект Bookmark. Resuming a pending workflow is now managed using a Bookmark object.
Более удобное расширение среды проектирования WF Designer Easier Ability to Extend WF Designer Experience
Новый конструктор WF основан на Windows Presentation Foundation (WPF) и предоставляет более простую модель для использования при повторном размещении конструктора WF вне Visual Studio, а также предоставляет более удобные механизмы для создания пользовательских конструкторов действий. The new WF Designer is built on Windows Presentation Foundation (WPF) and provides an easier model to use when rehosting the WF Designer outside of Visual Studio and also provides easier mechanisms for creating custom activity designers. Дополнительные сведения см. в разделе Настройка интерфейса рабочего процесса. For more information, see Customizing the Workflow Design Experience.
Windows Workflow Foundation Windows Workflow Foundation
В этом разделе описывается модель программирования, примеры и средства Windows Workflow Foundation (WF). This section describes the programming model, samples, and tools of the Windows Workflow Foundation (WF).
в этом разделе In This Section
Руководство по документации по рабочему процессу Windows Набор предлагаемых тем для чтения, в зависимости от ваших знаний (новичков в работе) и требований. Guide to the Windows Workflow Documentation A set of suggested topics to read, depending upon your familiarity (novice to well-acquainted), and requirements.
Новые возможности Windows Workflow Foundation Обсуждаются изменения в нескольких парадигмах разработки из предыдущих версий. What’s New in Windows Workflow Foundation Discusses the changes in several development paradigms from previous versions.
Новые возможности Windows Workflow Foundation в .NET Framework 4,5 Описание новых возможностей в Windows Workflow Foundation в .NET Framework 4.6.1 .NET Framework 4.6.1 . What’s New in Windows Workflow Foundation in .NET Framework 4.5 Describes the new features in Windows Workflow Foundation in .NET Framework 4.6.1 .NET Framework 4.6.1 .
Особенности Windows Workflow Foundation компонентов Описание новых функций в Windows Workflow Foundation в .NET Framework 4. Windows Workflow Foundation Feature Specifics Describes the new features in Windows Workflow Foundation in .NET Framework 4.
Общие сведения о рабочем процессе Windows Набор разделов, в которых обсуждаются более крупные понятия Windows Workflow Foundation. Windows Workflow Conceptual Overview A set of topics that discusses the larger concepts behind Windows Workflow Foundation.
Учебник по начало работы Набор пошаговых руководств, посвященных программированию Windows Workflow Foundation приложений. Getting Started Tutorial A set of walkthrough topics that introduce you to programming Windows Workflow Foundation applications.
Windows Workflow Foundation программирование Набор разделов учебника, которые следует понимать, чтобы стать хорошо знакомым WF WF программистам. Windows Workflow Foundation Programming A set of primer topics that you should understand to become a proficient WF WF programmer.
Расширение Windows Workflow Foundation Набор разделов, в которых обсуждается расширение или Настройка Windows Workflow Foundation в соответствии со своими потребностями. Extending Windows Workflow Foundation A set of topics that discusses how to extend or customize Windows Workflow Foundation to suit your needs.
Примеры рабочих процессов Windows Содержит примеры приложений, демонстрирующие функции и сценарии WF. Windows Workflow Samples Contains sample applications that demonstrate WF features and scenarios.
Workflow Core — движок бизнес-процессов для .Net Core
Мы решили поддержать тему миграции проекта, использующего Windows Workflow Foundation на .Net Core, которую начали коллеги из DIRECTUM, поскольку столкнулись с аналогичной задачей пару лет назад и пошли собственным путем.
Начнем с истории
Наш флагманский продукт Avanpost IDM — это система управления жизненным циклом учетных записей и правами доступа работников. Управлять доступом он умеет как автоматически на основании ролевой модели, так и по заявкам. На заре становления продукта у нас была достаточно простая система самообслуживания с простым пошаговым workflow, для которого движок не требовался в принципе.
Однако, столкнувшись с крупными клиентами, мы поняли, что требуется гораздо более гибкий инструмент, поскольку их требования к процессам согласования прав доступа стремились к правилам хорошего развесистого документооборота. Проанализировав требования, мы решили разработать собственный редактор процессов в формате BPMN, подходящий под наши нужды. Про разработку редактора с использованием React.js + SVG мы расскажем чуть позже, а сегодня обсудим тему бэкенда — workflow engine или движка бизнес-процессов.
Требования
На момент начала разработки системы у нас были следующие требования к движку:
- Поддержка схем процессов, понятный формат, возможность трансляции из нашего формата в формат движка
- Хранение состояния процесса
- Поддержка версионирования процессов
- Поддержка параллельного выполнения (веток) процесса
- Подходящая лицензия, позволяющая использовать решение в тиражируемом коммерческом продукте
- Поддержка горизонтального масштабирования
Проанализировав рынок (на 2014 год), мы остановились на фактически безальтернативном решении для .Net: Windows Workflow Foundation.
Windows Workflow Foundation (WWF)
WWF представляет собой технологию компании Microsoft для определения, выполнения и управления рабочими процессами.
Основу его логики составляет набор контейнеров для действий (активностей) и возможность из этих контейнеров строить последовательные процессы. Контейнер может быть обычным — некий шаг процесса, на котором выполняется активность. Может быть управляющим — содержащим в себе логику ветвления.
Процесс можно рисовать непосредственно в среде Visual Studio. Скомпилированная схема бизнес-процесса хранится в Хaml, что весьма удобно — формат описан, есть возможность сделать самописный дизайнер процессов. Это с одной стороны. А с другой — Xaml не самый удобный формат хранения описания — скомпилированная схема для более менее реального процесса получается огромной не в последнюю очередь из-за избыточности. Разобраться в ней очень сложно, а разбираться придется.
Но если со схемами рано или поздно можно постичь дзен и научится читать их, то вот отсутствие прозрачности работы самого движка добавляет хлопот уже во время эксплуатации системы пользователями. Когда ошибка исходит и недр Wf, узнать на 100%, в чем именно была причина сбоя, удается не всегда. Закрытость исходников и относительная монструозность делу не помогает. Часто фиксить баги приходилось по симптомам.
Справедливости ради тут стоит уточнить, что проблемы, описанные выше, по большей части преследовали нас из-за сильной кастомизации поверх Wf. Кто-нибудь из читателей точно скажет, что мы сами создали себе кучу проблем, а потом героически их решали. Нужно было делать самописный движок с самого начала. В целом, они будут правы.
В сухом остатке решение заработало достаточно стабильно и успешно ушло в продакшн. Но переход наших продуктов под .Net Core вынудил нас отказаться от WWF и искать другой движок бизнес-процессов, т.к. Windows Workflow Foundation по состоянию на май 2019 года так и не был переведен на .Net Core. Как мы искали новый движок — тема отдельной статьи, но в итоге мы остановились на Workflow Core.
Workflow Core
Workflow Core — это свободно распространяемый движок бизнес-процессов. Он разрабатывается под лицензией MIT, т.е его можно спокойно использовать в коммерческой разработке.
Активно делает его один человек, еще несколько периодически делают pull request. Есть порты на другие языки (Java, Python и еще несколько).
Движок позиционируется как легковесный. По сути это просто некий хост для последовательного выполнения сгруппированных по каким-либо бизнес-правилам действий.
У проекта есть документация в виде wiki. К сожалению, она описывает далеко не все возможности движка. Однако требовать полноценную документацию будет нагло — проект opensource, поддерживается одним энтузиастом. Поэтому Wiki вполне будет вполне достаточно для начала работы.
«Из коробки» есть поддержка хранения состояния процессов во внешних хранилищах (persistence storage). Стандартно идут провайдеры для:
- MongoDB
- SQL Server
- PostgreSQL
- Sqlite
- Amazon DynamoDB
Написать свой провайдер не составляет проблем. Берем исходники любого стандартного и делаем по примеру.
Поддерживается горизонтальное масштабирование, т.е можно запускать движок сразу на нескольких нодах, имея при этом одну точку хранения состояний процессов (один persistence storage). При этом размещение внутренней очереди задач движка должно быть в общем хранилище (rabbitMQ, как вариант). Для исключения выполнения одной задачи несколькими нодами одновременно предусмотрен диспетчер блокировок. По аналогии с провайдерами внешнего хранилища, есть стандартные реализации:
- Azure Storage Leases
- Redis
- AWS DynamoDB
- SQLServer (в исходниках есть, но в документации ничего не сказано)
Знакомство с чем-то новым проще всего начать с примера. Так и поступим. Я опишу с самого начала построение простого процесса, попутно давая свои пояснения. Пример может показаться до невозможности простым. Соглашусь — он простой. Самое то для начала.
Step (Шаг)
Шаг — это этап процесса, на котором выполняются какие либо действия. Весь процесс строится из последовательности шагов. Один шаг может выполнять много действий, может выполняется повторно, например, по некоторому событию извне. Есть набор шагов, которые наделены логикой «из коробки»:
Само собой, на одних встроенных примитивах процесс не постоишь. Нужны шаги, которые выполняют бизнес-задачи. Поэтому пока отложим их в сторону и сделаем шаги со своей логикой. Для этого нужно наследоваться от абстракции StepBody.
Метод Run выполняется, когда процесс заходит в шаг. В него и нужно разместить необходимую логику.
Шаги поддерживают внедрение зависимостей. Для этого достаточно зарегистрировать их в том же контейнере, что и необходимые зависимости.
Очевидно, что процессу нужен свой контекст — место, куда можно складывать промежуточные результаты выполнения. В wf core есть свой контекст выполнения процесса, который хранит информацию о его текущем состоянии. Получить доступ к нему можно, используя переменную context из метода Run(). В дополнение ко встроенному мы можем использовать свой контекст.
Подробнее способы описания и регистрации процесса разберем чуть ниже, пока просто определим свой некий класс — контекст.
В переменные Number запишем числа; в переменную StepResult — результат выполнения шага.
С контекстом определились. Можно писать свой шаг:
Логика крайне простая: на вход приходят два числа и название операции. Результат операции записывается в выходную переменную Result. Если операция не определена, то результат будет none.
С контекстом мы определились, шаг с нужней нам логикой тоже есть. Теперь нужно зарегистрировать наш процесс в движке.
Описание процесса. Регистрация в движке.
Описать процесс можно двумя способами. Первый — это описание в коде — хардкод.
Процесс описывается через fluent interface. Нужно отнаследоваться от обобщенного интерфейса IWorkflow , где T — класс контекста модели. В нашем случае это ProcessContext.
Выглядит это так:
Непосредственно описание будет внутри метода Build. Поля Id и Version также необходимо заполнить. Wf core поддерживает версионность процессов — можно зарегистрировать n версий процесса с одинаковым идентификатором. Это удобно, когда требуется обновить существующий процесс и при этом дать «дожить» уже существующим задачам.
Опишем простой процесс:
Если перевести на «человеческий» язык, получится примерно так: процесс начинается с шага CustomStep. Значение поля шага Input1 берется из поля контекста Number1, Значение поля шага Input2 берется из поля контекста Number2, полю Action жестко указано значение «sum». Выходные данные из поля Result записывается в поле контекста StepResult. Завершить процесс.
Согласитесь, код получился весьма читаемый, вполне можно разобраться, даже не имея особых познаний в C#.
Добавим к нашему процессу еще один шаг, который будет выводить в лог результат выполнения предыдущего шага:
И обновим процесс:
Теперь после шага с операцией сложения следует шаг вывода результата в лог. На вход мы передаем переменную Result и контекста, в которую на прошлом шаге записали результат выполнения. Возьму на себя смелость утверждать, что подобное описание через код (хардкод) в реальных системах будет малополезным. Разве что для каких-то служебных процессов. Куда более интересно иметь возможность хранить схему отдельно. Как минимум, нам не придется пересобирать проект каждый раз, когда нужно что-то поменять в процессе или добавить новый. Эту возможность wf core предоставляет посредством хранения схемы json. Продолжим расширять наш пример.
Json описание процесса
Далее я не буду приводить описание через код. Это не особо интересно, и только раздует статью.
Wf core поддерживает описание схемы в json. На мой взгляд, json более нагляден чем xaml (хорошая тема для холивара в комментариях 🙂 ). Структура файла довольно простая:
В поле DataType указывается полное имя класса контекста и имя сборки, в которой он описан. В Steps хранится коллекция всех шагов процесса. Заполним элемент Steps:
Давайте разберем подробнее структуру описание шага через json.
Поля Id и NextStepId хранят идентификатор данного шага и указатель, какой шаг может быть следующим. При этом порядок следования элементов коллекции неважен.
StepType аналогичен полю DataType, содержит полное имя класса шага (тип, который наследуется от StepBody и реализует логику шага) и название сборки. Дальше интереснее — объекты Inputs и Outputs. Они задаются в виде маппинга.
В случае Inputs имя элемента json — это имя поля класса нашего шага; значение элемента — имя поля в классе — контексте процесса.
Для Outputs наоборот, имя элемента json — это имя поля в классе — контексте процесса; значение элемента — имя поля класса нашего шага.
Почему поля контекста указываются именно через data. , а в случае Output — step. ? Потому что wf core значение элемента выполняет как C# выражение (используется библиотека Dynamic Expressions). Это довольно полезная вещь, с ее помощью можно закладывать некоторую бизнес-логику непосредственно внутри схемы, если, конечно, архитектор одобрит такое безобразие:).
Разнообразим схему стандартными примитивами. Добавим условный шаг If и обработку внешнего события.
Примитив If. Тут начинаются сложности. Если вы привыкли к bpmn и рисуете процессы в этой нотации, то вас ждет легкая подстава. По документации шаг описывается следующим образом:
Нет ощущения, что что-то тут не так? У меня есть. На вход шага задается Condition — выражение. Дальше задаем список шагов внутри массива Do (действия). Так, а где ветка False? Почему нет массива Do для False? На самом деле есть. Подразумевается, что ветка False — это просто проход дальше по процессу, т.е по указателю в NextStepId. Первое время я постоянно путался из-за этого. Окей, тут разобрались. Хотя нет. Если действия по процессу в случае True нужно класть внутрь Do, это же какой «красивый» json тогда будет. А если там этих If вложенных с десяток? Все уедет вбок. А еще говорят, что схему на xaml трудно читать. Есть небольшой хак. Просто взять монитор пошире. Немного выше упоминалось, что порядок шагов в коллекции значение не имеет, переход идет по указателям. Это можно использовать. Добавим еще один шаг:
Догадываетесь, к чему я веду? Верно, мы вводим служебный шаг, который транзитом переводит процесс на шаг в NextStepId.
Обновим нашу схему:
В шаге If проверяется, пустой ли результат выполнения шага Eval. Если не пустой, то выводим результат, если пустой — то сообщение «Empty result». Шаг Jump переводит процесс в шаг Output, который находится вне коллекции Do. Таким образом, мы сохранили «вертикальность» схемы. Также таким способом можно переходить по условию на n шагов назад, т.е. организовывать цикл. В wf core есть встроенные примитивы для циклов, но они не всегда удобны. В bpmn, например, циклы организуются через If.
Использовать этот подход или стандартный, решать уже вам. Для нас такая организация оказалась шагов удобнее.
WaitFor
Примитив WaitFor дает возможность внешнему миру влиять на ход процесса, когда он уже запущен. Например, если на этапе процесса требуется одобрение дальнейшего хода каким-либо пользователем. Процесс будет стоять на шаге WaitFor, пока в него не придет событие, на которое он подписан.
Немного поясню параметры.
CancelCondition — условие прерывания ожидания. Предоставляет возможность прервать ожидание события и пойти дальше по процессу. Например, если процесс одновременно ждет n разных событий (wf core поддерживает параллельное выполнение шагов), ждать прихода всех не требуется, в этом случае нам поможет CancelCondition. Добавляем в переменные контекста логический флаг и при получении события выставляем флаг в значение true — все шаги WaitFor завершатся.
EventName и EventKey — имя и ключ события. Поля нужны, чтобы в реальной системе с большим количеством одновременно работающих процессов, различать события, т.е. чтобы движок понимал, какое событие для какого процесса и какого шага предназначено.
EffectiveDate — опциональное поле, добавляет событию метку времени. Может пригодится в случае, если нужно опубликовать событие «в будущее». Чтобы оно опубликовалось сразу параметр можно оставить пустым или задать текущее время.
Далеко не во всех случаях удобно делать отдельный шаг для обработки реакций извне, скорее даже обычно он будет избыточен. Лишнего шага можно избежать, добавив в обычный шаг ожидание внешнего события и логику его обработки. Дополним шаг CustomStep подпиской на внешнее событие:
Мы воспользовались стандартным методом расширения WaitForEvent(). Он принимает на вход уже упомянутые ранее параметры EventName, EventKey и EffectiveDate. После выполнения логики такого шага процесс встанет в ожидание описанного события и снова вызовет метод Run() в момент публикации события в шине движка. Однако в текущем виде мы не можем различить моменты первичного входа в шаг и вход после события. А хотелось бы как-то разделить логику до-после на уровне шага. И в этом нам поможет флаг EventPublished. Он находится внутри общего контекста процесса, получить его можно так:
Опираясь на этот флаг можно спокойно разделить логику на до и после внешнего события.
Важное уточнение — по задумке создателя движка один шаг может быть подписать только на один эвент и среагировать на него один раз. Для некоторых задач это весьма неприятное ограничение. Нам даже пришлось «допиливать» движок, чтобы от этого нюанса уйти. Сейчас в этой статье их описание пропустим, иначе статья никогда не закончится :). Более сложные практики использования и примеры доработок будут освещаться в последующих статьях.
Регистрация процесса в движке. Публикация события в шину.
Итак, с реализацией логики шагов и описания процесса разобрались. Осталось самое главное, без чего процесс не будет работать — описание нужно зарегистрировать.
Воспользуемся стандартным методом расширения AddWorkflow(), который разместит в нашем IoC контейнере свои зависимости.
Выглядит он так:
IServiceCollection — интерфейс — контракт коллекции описаний сервисов. Он живет внутри DI от Microsoft (подробнее про него можно почитать тут)
WorkflowOptions — базовые настройки движка. Самому их задавать не обязательно, стандартные значение вполне приемлемы для первого знакомства. Едем дальше.
Если процесс описывался в коде, то регистрация происходит так:
Если процесс описан через json, то его нужно регистрировать так (само собой, json описание нужно предварительно загрузить из места хранения):
Далее для обоих вариантов код будет одинаков:
Параметр definitionId — идентификатор процесса. То, что записано в поле Id процесса. В данном случае идентификатор = SomeWorkflow.
Параметр version указывает, какую версию процесса запустить. Движок предоставляет возможность регистрировать сразу n версий процесса с одним идентификатором. Это удобно, когда требуется внести изменения в описание процесса, не ломая уже запущенные задачи — новые будут создаваться по новой версии, старые спокойно доживут на старой.
Параметр context — экземпляр контекста процесса.
Методы host.Start() и host.Stop() запускают и останавливают хостинг процессов. Если в приложении запуск процессов — прикладная задача и выполняется периодически, то следует останавливать хостинг. Если приложение имеет основным направлением выполнение различных процессов, то хостинг можно не останавливать.
Для передачи сообщений из внешнего мира в шину движка, которая потом распределит их по подписчикам есть метод:
Описание его параметров было выше в статье (см. часть про WaitFor примитив).
Заключение
Мы определенно рисковали, когда приняли решение в пользу Workflow Core — opensource проекта, который активно разрабатывает один человек, да еще и с весьма бедной документацией. И реальных практик использования wf core в рабочих системах (кроме нашей) вы, скорее всего, не найдете. Конечно, выделив отдельный слой абстракций, мы подстраховались на случай неуспеха и необходимости быстро вернутся к WWF, например, или самописному решению, но все пошло вполне неплохо и неуспех не настал.
Переход на opensource движок Workflow Core решил определенное количество проблем, которые мешали нам спокойно жить на WWF. Самая главная из них — это, конечно же, поддержка .Net Core и отсутствие таковой, даже в планах, у WWF.
Следом идет открытость исходников. Работая с WWF и получая разнообразные ошибки из его недр, возможность хотя бы почитать исходники была бы очень кстати. Не говоря уже о том, чтобы что-то в них поменять. Тут с Workflow Core полная свобода (в том числе по лицензированию — MIT). Если вдруг появляется ошибка из недр движка, просто качаем исходники из github и спокойно ищем причину ее возникновения. Да просто возможность запустить движок в режиме отладки с точками останова уже сильно облегчает процесс.
Само собой, решив одни проблемы, Workflow Core принес уже свои, новые. Нам пришлось внести ощутимое количество изменений в ядро движка. Но. Работы по «допиливанию» под себя обошлись дешевле по времени, чем разработка собственного движка с нуля. Итоговое решение получилось вполне приемлемо по скорости и стабильности работы, позволило нам на текущий момент забыть про проблемы с движком и сфокусироваться на развитии бизнес-ценности продукта.