Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Slickflow.NET Core Open Source Workflow Engine

0.00/5 (No votes)
1 Dec 2019 5  
Slickflow.NET Core Open Source Workflow Engine

Introduction

For developers eager to understand the engine function, after downloading the version, they want to try to write code to complete the development and testing of a process. This article attempts to illustrate how to quickly understand engine code writing from a simple process.

Background

.NET/.NET Core Workflow Engine With Full Source Code

Github: https://github.com/besley/Slickflow

  1. .NET, .NET CORE version both supported: Slickflow is an open source project based on .NET Framework 4.5, .NET CORE 2; It's easy to use engine product into cross platform application.
  2. BPMN graphic style process diagram: Slickflow is using BPMN notation to descript process diagram, the Slickflow designer is HTML5 graph editor and user friendly to business process communication and business analysis.
  3. High performance with Dapper.NET library: Dapper is a simple object mapper for .NET and own the title of King of Micro ORM in terms of speed and is virtually as fast as using a raw ADO.NET data reader. An ORM is an Object Relational Mapper, which is responsible for mapping between database and programming language. (Reference: https://dapper-tutorial.net/dapper)
  4. Multiple database supported: Slickflow supports SQLSERVER, ORACLE, MySQL and other database, it implemented by Dapper.NET extension library. The .NET Core version using EF core to support different database products.
  5. Workflow patterns supported:

    Wokflow Pattern

    1. Sequence: The most frequently process pattern
    2. Split/Merge: Support and/or gateway such as and/or split, and/or join, together with condition variables on the transition
    3. Sub-process: In the main process, a sub process node can start a new process life cycle.
    4. Multi-instance: Multiple performers processing a task together by multiple task instances. All performers both compete their task, then the process can be continued on. There are sequence and parallel pattern, and the percentage or count parameters can be set on it to ensure when you can go to the next step.

      Muliple Instance Pattern

    5. Event interoperation: Process instance and activity instance event delegation service, such as process/activity start, execute and complete. The event is also supported to call external method through the configuration of the node on the property page. such as WebApi, SQL, StoreProcedure and Python script.
    6. Timer: Integrated with HangFire library, and with CRON expression supported
    7. Email: To do or overdue tasks email notification
    8. Withdraw: Withdraw the task after just being sent out to next step users.
    9. Sendback: Send back to previous step user, because there are some exceptions.
    10. Resend: Combined after sendback and re-send the task to original sendback users.
    11. Reverse: Reverse the process instance alive when completed doing them.
    12. Jump: Jump the process over by several steps forward or backward.
  6. Process Version: The process has version property to upgrade a new definition due to business process changed.
  7. XML Cache: The runtime instance uses cache to keep XML process diagram by an expired duration.

Using the Code

I: Simple Sequential Process Coding Example

Foreword: For developers eager to understand the engine function, after downloading the version, they want to try to write code to complete the development and testing of a process.This article attempts to illustrate how to quickly understand engine code writing from a simple process.

Version: .NET Core 2.1

1. Create Flow Chart

Sequence is used to create sequential processes, and nodes are generated sequentially.

var pmb = ProcessModelBuilder.CreateProcess("BookSeller Process", "BookSeller Process Code", "1");
var process = pmb.Start("Start")
      .Task("Package Books", "PB001")
      .Task("Deliver Books", "DR001")
      .End("End")
      .Store();

The above code creates a simple serial process with four nodes, the start node, two task nodes and the Store() method is used for database storage process. Examples of flow charts are as follows:

Sequence Flow Chart

2. Process Startup and Operation

Starting and running processes are the two most commonly used API interfaces.

2.1 Process Startup

Starting needs to deal with the creation of process instances, as well as the creation of task nodes after the start node. The sample code is as follows:

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("10", "jack")
             .UseApp("BS-100", "Delivery-Books", "BS-100-LX")
             .UseProcess("BookSellerProcessCode ")
             .Start( );

Process Record List:

Sequence Activity Instance

2.2 Process Running

Process running is a process that starts with the current to-do task and runs to the next step. When parsing a process, there may be multiple processing steps in the next step, requiring the user to explicitly select a list of steps (usually specified by the front-end user when the next step list pops up). Here, an example can be used to run as a simple one-step instance.

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("10", "jack")
        .UseApp("BS-100", "Delivery-Books", "BS-100-LX")
        .UseProcess("BookSellerProcessCode ")
        .OnTask(8027) // TaskID
        .NextStepInt("20", "Alice")
        .Run( );

Process Record List:

Sequence Activity Instance After Running

3. Process Withdraw and SendBack

3.1 Process Withdraw

If the user finds an error message when he completes his to-do task and sends it to the next dealer, he can initiate the revocation by himself and revoke the current process back. Revoking internal processing logic is equivalent to returning processing, except that the sponsors are in different positions. The code example is as follows:

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("20", "Alice")
           .UseApp("BS-100", "Delivery-Books", "BS-100-LX")
           .UseProcess("BookSellerProcessCode ")
           .OnTask(8027) // TaskID
           .Withdraw( );

Process Record List:

Sequence Activity Instance After Withdraw

3.2 Process SendBack

The process return is initiated by the current to-do task handler and returns to the previous step of the process. When parsing a process, the previous step may have multiple processing steps, requiring the user to explicitly select a list of steps (usually specified by the front-end user when the previous step list pops up), and the PrevStepInt () method is used to simplify processing for only one of the processing steps that are returned.

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("20", "Alice")
            .UseApp("BS-100", "Delivery-Books", "BS-100-LX")
            .UseProcess("BookSellerProcessCode ")
            .PrevStepInt()
            .OnTask(8030) // TaskID
            .SendBack( );

Process Record List:

Sequence Activity Instance After SendBack

II: Simple Parallel Branch Process Code Writing Example

Foreword: For developers eager to understand the engine function, after downloading the version, they want to try to write code to complete the development and testing of a process. This article attempts to illustrate how to quickly understand engine code writing from a simplest parallel branching process.

Version: .NET Core 2.1

1. Create Branch Flow Chart

Branch process is a common decision-making process. In this paper, a car order process is taken as an example to demonstrate the process of parallel branch process. Parallel branches are usually used in scenarios where multiple departments can perform tasks at the same time, and each individual branch can also be considered as a serial sequence fragment. Finally, multiple branches are merged through the sink node.

var pmb = ProcessModelBuilder.CreateProcess(" LargeOrderProcess ", " LargeOrderProcessCode ");
var process = pmb.Start("Start")
           .Task("Large Order Received", "LOR001")
           .AndSplit("AndSplit")
           .Parallels(
               () => pmb.Branch (
                    () => pmb.Task("Engineering Review", "ER001")
                  )
                  , ( ) => pmb.Branch (
                    () => pmb.Task("Design Review", "DR001")
                  )
                )
           .AndJoin("AndJoin")
           .Task("Management Approve", "MA001")
           .End("End")
           .Store(); 

The above code creates a parallel branching process with two branches, and the branch is AndSplit-AndJoin. The attribute types of the nodes in the graph are set by direct assignment of the code. Examples of flow charts are as follows:

parallel flowchart

2. Process Startup and Operation

Starting and running processes are the two most commonly used API interfaces.

2.1. Process Startup

Starting needs to deal with the creation of process instances, as well as the creation of task nodes after the start node and the start node. The sample code is as follows:

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("10", "jack")
           .UseApp("PS-100", "Large-Car-Order", "PS-100-LX")
           .UseProcess("LargeOrderProcessCode")
           .Start( );

The activity instance record table is as follows:

Parallel Activity Instance After Startup

2.2. Process Running

Process running is a process that starts with the current to-do task and runs to the next step. Parallel branches indicate that multiple branches are triggered simultaneously, as illustrated in the flow chart above: Design Review and Engineering Review are triggered simultaneously by parallel gateway nodes (AndSplit), so two new activity records are generated at one time in the activity instance table.

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("10", "jack")
         .UseApp("PS-100", "Large-Car-Order", "PS-100-LX")
         .UseProcess("LargeOrderProcessCode ")
         .OnTask( 8033)
         .NextStepInt("20", "Alice")
         .Run( );

The activity instance record table is as follows:

Parallel Activity Instance After Running

3. Withdraw and SendBack

3.1 Process Withdraw

If the user finds an error message when he completes his to-do task and sends it to the next dealer, he can initiate the revocation by himself and revoke the current process back. When the parallel branch is withdrawn, the two parallel branches are also set back and revoked at the same time, indicating that the branch is two activities of strong correlation type.

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("10", "Jack")
         .UseApp("PS-100", "Large-Car-Order", "PS-100-LX")
         .UseProcess("LargeOrderProcessCode ")
         .OnTask(8033) // TaskID
         .Withdraw( );

   The activity instance record table is as follows:

Parallel Activity Instance After Withdraw

3.2 Process SendBack

The process return is initiated by the current to-do task handler and returns to the previous step of the process. If one branch of a parallel branch is returned, then the default is to return only the task node before the current branch to the gateway, without affecting the other branch.

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("20", "Alice")
          .UseApp("PS-100", "Large-Car-Order", "PS-100-LX")
          .UseProcess("LargeOrderProcessCode ")
          .PrevStepInt()
          .OnTask( 8038) // TaskID
          .SendBack( );

The activity instance record table is as follows:

Parallel Activity Instance After SendBack

Revocation and fallback of parallel branches are special in the engine because of the processing of adjacent branches. Here, only the result records after the return are described, and the internal processing logic of the return will be arranged for another article to be introduced specifically in the future.

III: Simple or Branched Process Coding Example

Foreword: For developers eager to understand the engine function, after downloading the version, they want to try to write code to complete the development and testing of a process.This paper attempts to quickly understand the engine code writing from the leave process or branch mode.

Version: .NET CORE 2.1

1. Create or Branch Flow Charts

Or branching process is a common decision-making process, which is used to deal with business processing in different decision scenarios, in which each branch can be regarded as a fragment of a serial process. The following is the creation code of the leave process:

var pmb = ProcessModelBuilder.CreateProcess(" LeaveRequest ", " LeaveRequestCode ");
var process = pmb.Start("Start")
         .Task("Fill Leave Days", "FLD001")
         .OrSplit("OrSplit")
         .Parallels(
                  () => pmb.Branch(
                     () => pmb.Task(
                              VertexBuilder.CreateTask("CEO Evaluate", "CEOE001"),
                              LinkBuilder.CreateTransition("days>=3")
                                 .AddCondition( ConditionTypeEnum.Expression , "Days>=3")
                              )
                      )
                 , () => pmb.Branch(
                     () => pmb.Task(
                              VertexBuilder.CreateTask("Manager Evaluate", "ME001"),
                              LinkBuilder.CreateTransition("days<3")
                                 .AddCondition(ConditionTypeEnum.Expression, "Days<=3")
                              )
                      )
                  )
          .OrJoin("OrJoin")
          .Task("the Notify HR", "HRN001")
          .End("End")
          .Store( );

The above code creates an OrSplit-OrJoin process with two branches representing the leave process in the actual business process. An example of the completed flow chart is as follows:

Decision Flowchart

Or the branch is a transition of two conditional expressions. In the case of a branch gateway node, the process will decide which branch to take according to the value of the incoming conditional variable days. This process can be regarded as the branch selection of the number of days off in the leave process. For example, if the number of days off is less than 3 days, the Department Manager will approve it. If the number of days off exceeds (including) 3 days, the general manager will be required to approve it. Approval decision-making can be realized by means of branch mode or branch mode.

2. Process Startup and Operation

Starting and running processes are the two most commonly used API interfaces.

2.1. Process Startup

Starting needs to deal with the creation of process instances, as well as the creation of task nodes after the start node and the start node. The sample code is as follows:

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("10", "jack")
          .UseApp("DS-100", "Leave-Request", "DS-100-LX")
          .UseProcess("LeaveRequestCode ")
          .Start( );

The activity instance record table is as follows:

Decision Activity Instance After Startup

Similarly, according to the leave process as an example, the first task node can be regarded as "submitting leave form", and when the employee completes the leave form, it can be regarded as starting the process.

2.2 Process Running

Process running is a process that starts with the current to-do task and runs to the next step. Because it's a branch gateway or a branch gateway, it's necessary to specify the name and value of the condition variable to determine the next branch path. Here, the days of leave as a conditional variable need to be passed in. When the days of leave are 3 days, the gateway decides to the CEO approval node, so only one of the branches will be selected for routing. The code example is as follows:

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("10", "jack")
      .UseApp("DS-100", "Leave-Request", "DS-100-LX")
      .UseProcess("LeaveRequestCode ")
      .OnTask( 8017)
      .IfCondition("Days", "3")
      .NextStepInt("20", "Alice")
      .Run( );

The activity instance record table is as follows:

Decison Activity Instance After Running

3. Withdraw and SendBack of Process

3.1. Process Withdraw

If the user finds an error message when he completes his to-do task and sends it to the next dealer, he can initiate the revocation by himself and revoke the current process back.

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("10", "Jack")
         .UseApp("DS-100", "Leave-Request", "DS-100-LX")
         .UseProcess("LeaveRequestCode ")
         .OnTask(8017) // TaskID
         .Withdraw ( );

   The activity instance record table is as follows:

Decision Activity Instance After Withdraw

3.2 Process SendBack

The process return is initiated by the current to-do task handler and returns to the previous step of the process. If one branch of a parallel branch is returned, then the default is to return only the task node before the current branch to the gateway, without affecting the other branch.

IWorkflowService wfService = new WorkflowService( );
var wfResult = wfService.CreateRunner("20", "Alice")
      .UseApp("DS-100", "Leave-Request", "DS-100-LX")
      .UseProcess("LeaveRequestCode ")
      .PrevStepInt()
      .OnTask(8020) // TaskID
      .SendBack( );

The activity instance record table is as follows:

Decision Activity Instance After SendBack

Development Tools

1) Slickflow Process Designer

2) Slickflow WebTest Tools

GitHub Project

Summary

  1. The above code can help developers quickly familiarize themselves with the interface of engine components and the practical functions of simple or branch. The complete functions need to be acquired in the enterprise version or above.
  2. Process Designer and Web Testing Tool in the Assistant Development Tool, which can give users intuitive experience operation, but also suitable for different types of business users;
  3. Code creation process and test process are convenient for developers to learn and start quickly, which is an efficient way to improve work efficiency.

History

  • 21st September, 2019: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here