我们已经知道了如何使用Fluent API定义流程和如何注册流程,现在我们需要了解如何定义流程需要处理的数据,和如何进行数据传递。这里举一个最简单的例子来说明。在前面的例子中,我们输出“你好”和“再见”,现在扩展这个需求,流程启动后,等待用户输入名字,然后输出“你好,<输入的名字>”和“<输入的名字>,再见”。为了完成这个需求,需要:
- 定义一个数据结构用来保存输入的名字
- 将这个数据结构与流程关联起来
- 修改流程,让流程等待用户输入
- 将用户输入的变量传递给流程
首先我们定义一个简单的类,用来保存输入的名字:
namespace ZL.WorflowCoreDemo.InputDataToStep
{
public class MyNameClass
{
public string MyName { get; set; }
}
}
然后,修改流程的定义:
using System;
using WorkflowCore.Interface;
using WorkflowCore.Models;
using ZL.WorflowCoreDemo.InputDataToStep.Steps;
namespace ZL.WorflowCoreDemo.InputDataToStep
{
public class HelloWithNameWorkflow : IWorkflow<MyNameClass>
{
public string Id => "HelloWithNameWorkflow";
public int Version => 1;
public void Build(IWorkflowBuilder<MyNameClass> builder)
{
builder
.StartWith(context => ExecutionResult.Next())
.WaitFor("MyEvent", (data, context) => context.Workflow.Id, data => DateTime.Now)
.Output(data => data.MyName, step => step.EventData)
.Then<HelloWithName>()
.Input(step => step.Name, data => data.MyName)
.Then<GoodbyeWithName>()
.Input(step => step.Name, data => data.MyName);
}
}
}
这里,流程声明为 IWorkflow<MyNameClass>,说明流程使用这个类存储数据,在流程定义中,可以使用data操作相关的数据对象,比如: .Input(step => step.Name, data => data.MyName) 就是将流程数据中的MyName传递给步骤中的Name(step.Name)。
这段代码中还使用WaitFor定义了一个事件,这个事件的输出是将事件接收的外部参数(step.EventData)传递给流程的MyName属性。
还需要修改两个步骤,增加名称字段:
using System;
using System.Collections.Generic;
using WorkflowCore.Interface;
using WorkflowCore.Models;
namespace ZL.WorflowCoreDemo.InputDataToStep.Steps
{
public class HelloWithName : StepBody
{
public string Name { get; set; }
public override ExecutionResult Run(IStepExecutionContext context)
{
Console.WriteLine("你好," + Name);
return ExecutionResult.Next();
}
}
}
using System;
using WorkflowCore.Interface;
using WorkflowCore.Models;
namespace ZL.WorflowCoreDemo.InputDataToStep.Steps
{
public class GoodbyeWithName : StepBody
{
public string Name { get; set; }
public override ExecutionResult Run(IStepExecutionContext context)
{
Console.WriteLine(Name + ",再见");
return ExecutionResult.Next();
}
}
}
下面是流程注册和运行的代码:
using System;
using WorkflowCore.Interface;
using WorkflowCore.Models;
using ZL.WorflowCoreDemo.InputDataToStep.Steps;
namespace ZL.WorflowCoreDemo.InputDataToStep
{
public class HelloWithNameWorkflow : IWorkflow<MyNameClass>
{
public string Id => "HelloWithNameWorkflow";
public int Version => 1;
public void Build(IWorkflowBuilder<MyNameClass> builder)
{
builder
.StartWith(context => ExecutionResult.Next())
.WaitFor("MyEvent", (data, context) => context.Workflow.Id, data => DateTime.Now)
.Output(data => data.MyName, step => step.EventData)
.Then<HelloWithName>()
.Input(step => step.Name, data => data.MyName)
.Then<GoodbyeWithName>()
.Input(step => step.Name, data => data.MyName);
}
}
}
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using WorkflowCore.Interface;
namespace ZL.WorflowCoreDemo.InputDataToStep
{
public class FlowRun
{
public static void Run()
{
IServiceProvider serviceProvider = ConfigureServices();
var host = serviceProvider.GetService<IWorkflowHost>();
host.RegisterWorkflow<HelloWithNameWorkflow, MyNameClass>();
host.Start();
var initialData = new MyNameClass();
var workflowId = host.StartWorkflow("HelloWithNameWorkflow", 1, initialData).Result;
Console.WriteLine("输入名字");
string value = Console.ReadLine();
host.PublishEvent("MyEvent", workflowId, value);
Console.ReadLine();
host.Stop();
}
private static IServiceProvider ConfigureServices()
{
//setup dependency injection
IServiceCollection services = new ServiceCollection();
services.AddLogging();
services.AddWorkflow();
var serviceProvider = services.BuildServiceProvider();
return serviceProvider;
}
}
}
运行效果如下:
我们也可以使用字典作为数据对象,流程的定义如下:
using System;
using System.Collections.Generic;
using WorkflowCore.Interface;
using WorkflowCore.Models;
using ZL.WorflowCoreDemo.InputDataToStep.Steps;
namespace ZL.WorflowCoreDemo.InputDataToStep
{
public class HelloWithNameWorkflowDynamic : IWorkflow<Dictionary<string,string>>
{
public string Id => "HelloWithNameWorkflowDynamic";
public int Version => 1;
public void Build(IWorkflowBuilder<Dictionary<string, string>> builder)
{
builder
.StartWith(context => ExecutionResult.Next())
.WaitFor("MyEvent", (data, context) => context.Workflow.Id, data => DateTime.Now)
.Output((step,data)=>data.Add("Name",(string)step.EventData))
.Then<HelloWithName>()
.Input(step => step.Name, data => data["Name"])
.Then<GoodbyeWithName>()
.Input(step => step.Name, data => data["Name"]);
}
}
}
这里没有使用自定义的类,而是使用了字典Dictionary<string, string>,流程的运行代码如下:
IServiceProvider serviceProvider = ConfigureServices();
var host = serviceProvider.GetService<IWorkflowHost>();
host.RegisterWorkflow<HelloWithNameWorkflowDynamic, Dictionary<string,string>>();
host.Start();
var initialData = new Dictionary<string,string>();
var workflowId = host.StartWorkflow("HelloWithNameWorkflowDynamic", 1, initialData).Result;
Console.WriteLine("输入名字");
string value = Console.ReadLine();
host.PublishEvent("MyEvent", workflowId, value);
Console.ReadLine();
foreach (var key in initialData.Keys)
{
Console.WriteLine(key + ":" + initialData[key]);
}
Console.ReadLine();
host.Stop();
可以从github下载完整的代码:https://github.com/zhenl/ZL.WorflowCoreDemo