Easy.WorkFlow.Core
2.3.14
dotnet add package Easy.WorkFlow.Core --version 2.3.14
NuGet\Install-Package Easy.WorkFlow.Core -Version 2.3.14
<PackageReference Include="Easy.WorkFlow.Core" Version="2.3.14" />
<PackageVersion Include="Easy.WorkFlow.Core" Version="2.3.14" />
<PackageReference Include="Easy.WorkFlow.Core" />
paket add Easy.WorkFlow.Core --version 2.3.14
#r "nuget: Easy.WorkFlow.Core, 2.3.14"
#:package Easy.WorkFlow.Core@2.3.14
#addin nuget:?package=Easy.WorkFlow.Core&version=2.3.14
#tool nuget:?package=Easy.WorkFlow.Core&version=2.3.14
Easy.WorkFlow.Core
Easy.WorkFlow.Core 是一个灵活、可扩展的工作流核心库,旨在简化工作流的定义、创建和执行过程。本库支持 .NET Standard 2.1、.NET 6、.NET 7、.NET 8 和 .NET 9。 Easy.WorkFlow.Core 目前仍在开发测试中,请谨慎使用。
功能特性
- 灵活的工作流定义:支持自定义工作流结构和步骤逻辑
- 多种步骤处理器类型:内置 SQL、Action(方法)和远程 URL 处理器
- 表达式解析:支持条件表达式和参与者(步骤审批人)表达式的动态解析(从工作流表单数据中解析)
- 可扩展架构:基于接口设计,易于扩展和自定义
- 完整的生命周期管理:从工作流定义、实例创建到执行完成的全流程支持
- 依赖注入支持:与 ASP.NET Core 依赖注入系统无缝集成
核心组件
- 工作流构建器 (WorkFlow Builder):负责创建工作流定义
- 工作流激活器 (WorkFlow Activator):负责创建工作流实例
- 工作流调度器 (WorkFlow Scheduler):负责调度和执行工作流步骤
- 步骤处理器 (Step Processor):处理不同类型的工作流步骤
- 步骤执行器 (Step Processor Executor):执行步骤处理器并处理结果
- 表达式解析器 (Expression Parser):解析条件表达式和参与者表达式
更新日志
- 2.3.14
- 新增:处理器上下文支持工作流执行上下文中提取属性值的占位符,如[WFInstanceId][WFName]等
- 2.3.13
- 新增:新增工作流实例显示名称(方便搜索)。
- 修复:修复工作流处理器部分参数绑定无效问题。
- 2.3.12
- 修复:修复默认远程处理器token传递到错误的header字段。
- 2.3.11
- 新增:WorkflowHandler部分钩子函数增加了WorkflowExecutionContext参数,表示工作流的执行上下文。
- 2.3.10
- 修复:修复工作流调度器事务嵌套导致事务不生效的问题
- 2.3.9
- 调整:取消IServiceResolver,改为原生的IServiceProvider。
- 2.3.8
- 新增:Workflow执行上下文及请求上下文添加IServiceResolver服务解析器(抽象接口),在需要时可以通过它解析依赖注入的服务。
- 2.3.7
- 调整:调整默认序列化配置,运用常用配置项。
- 2.3.6
- 调整:调整ParserOptions的UserIdKey及UserNameKey,支持多键名匹配。
- 2.3.5
- 新增:新增了IUnitOfWork接口,工作流调度器使用IUnitOfWork进行事务控制。
- 2.3.4
- 调整:调整了默认序列化器的配置,添加了long转换器及日期转换器,支持string转long,long转string防止精度丢失,支持非iso格式的日期转换。
- 新增:WorkFlowBuilderContext新增UpdateMode属性,表示是否更新模式,当UpdateMode为true时,更新模式下会忽略AutoGenerateId属性,直接使用传入的工作流定义对象的Id。
- 2.3.3
- 修复:修复了net6.0/7.0/standard2.1包依赖版本不正确的问题。
- 2.3.2
- 升级:底层依赖包升级到9.0.7版本
- 修复:修复了当注册了自定义IExpressionParser服务时未注册ParserOptions的错误。
- 调整:调整IExpressionParser接口方法为异步方法。
- 2.3.1
- 修复:修复了DefaultWorkFlowBuilder默认构建器step步骤id赋值错误的问题
- 2.3.0
- 修复:修复了When条件表达式当运算符前后存在空格无法正常解析的问题;修复默认的action处理器无法正常绑定外部参数的问题。
- 新增:WorkFlowBuilderContext新增AutoGenerateId属性,用于控制在工作流构建过程中是否使用自动生成id。
- 新增:WorkFlowService在构建完工作流后根据id查找是否已存在工作流决定是新增工作流还是更新现有工作流。
- 新增:IJsonSerializer添加Deserialize及GetDefaultJsonSerializerOptions方法。
- 新增:IRemoteProcessor、IActionProcessor、ISqlProcessor的ExecuteSqlProcessorAsync方法增加表示工作流执行上下文的参数;默认的处理器添加了OnExcute虚方法,方便重写实现自定义逻辑。
- 新增:WorkFlowExcutionContex执行上下文参数增加HasNext属性(表示是否有下一步骤)及Next委托(Next委托用于自我执行下一步骤,在FluentBuilder构建的基于类的处理器中可方便实现自我执行下一步)
- 调整:一些逻辑的重构调整
- 其他:新增了Easy.WorkFlow.FluentBuilder包,可通过Fluent Api以编程的方式构建工作流。
- 2.2.2
- WorkFlowBuilderContext新增Extras附加数据属性,允许在工作流构建过程中传递额外信息。
- WorkFlowHandler的OnBuildedAsync方法新增WF参数(构建成功后返回的表示工作流定义的.net 对象),允许在工作流构建完成后进行额外处理。
- 2.2.1
- 添加注释文档
- 完善使用说明
- 2.2.0
- 新增WorkFlow专用异常类WorkFlowException。
- 新增WorkFlow统一规范化结果返回WorkFlowResult。
- 新增统一结果提供服务IWorkFlowResultProvider,支持统一结果内容的返回处理。
- 调整原工作流核心装饰器服务名称为WorkFlowHandler(工作流服务处理器)。
- 新增基于约定的工作流服务处理器注册方式,继承WorkFlowHandler即可被WorkFlow扫描发现。
- 新增统一结果提供服务的注册,可通过UseWorkFlowResultProvider<T>注册或直接实现一个IWorkFlowResultProvider类即可被WorkFlow扫描发现。
- 2.1.0
- 新增全局异常处理
- 新增日志记录
- 支持自定义工作流核心装饰器服务
- 支持自定义工作流全局异常处理器
快速开始
1. 安装包
dotnet add package Easy.WorkFlow.Core
2. 注册服务
在 Program.cs
或 Startup.cs
中注册工作流服务:
// 基本注册
services.AddWorkFlow();
// 带配置的注册
services.AddWorkFlow(options =>
{
//2.2.0新增
// 自定义注册工作流处理器服务(2.1.0原名称:UseWorkFlowDecoratorService)
// 或在你的项目中可直接继承默认的 WorkFlowHandler,无需注册即可被扫描发现。
options.UseWorkFlowHandler<YourWorkFlowHandler>();
//2.2.0新增
// 自定义注册统一结果提供服务
// 或在你的项目中直接实现IWorkFlowResultProvider,无需注册即可被扫描发现。
options.UseWorkFlowResultProvider<YourResultProvider>();
// 2.1.0新增
options.EnableGlobalExceptionHandling=true; // 启用全局异常处理,默认开启
options.RethrowExceptions=false; // 是否重新抛出异常,默认不抛出。
// 2.1.0新增(2.2.0用UseWorkFlowHandler替代)
// 自定义注册工作流核心装饰器服务,建议继承自默认的 WorkFlowHandler 类实现
// 该装饰器可以在工作流执行前后添加额外的逻辑,可重写on开头的钩子方法。
//options.UseWorkFlowDecoratorService<YourWorkFlowDecorator>();
// 2.1.0新增
// 自定义注册工作流全局异常处理器,需实现 IWorkFlowExceptionHandler 接口。
options.UseExceptionHandler<YourWorkFlowExceptionHandler>();
// 配置是否等待处理器完成
options.WaitForProcessor = true;
// 配置工作流表单数据的默认序列化行为
options.JsonSerializer=(object? data)=>{
// 使用你项目中安装的序列化器去序列化工作流表单数据,不配置默认使用System.Tex.Json序列化
return JsonConvert.SerializeObject(jtoken);
};
// 自定义工作流构建器,需实现IWorkFlowBuilder,不配置默认采用库自带的构建器,自带的构建器是从内存对象直接构建的,你可以实现基于json或xml的构建
options.UseWorkFlowBuilder<Yourbuilder>();
//自定义Id生成器,工作流实例Id生成器,需实现 IIdGenerator 接口,默认有个DefaultIdGenerator 可以生成分布式id
options.UseIdGenerator<YourIdGenerator>();
//你的自定义Action处理器;工作流处理器类型为Action时会调用该处理器,需实现 IActionProcessor 接口,不配置就使用库自带的默认处理器
options.UseActionProcessor<YourActionProcessor>();
//你的SQL处理器;工作流处理器类型为SQL时会调用该处理器,需实现 ISqlProcessor 接口,不配置就使用库自带的默认处理器
//Easy.WorkFlow.SqlSugar包提供了基于SqlSugar的Sql处理器,可以实现基于sql的步骤处理。
options.UseSqlProcessor<YourSqlProcessor>();
//你的远程处理器;工作流处理器类型为远程URL时会调用该处理器,需实现 IRemoteProcessor 接口,不配置就使用库自带的默认处理器
// 默认远程处理器基于HttpClient发生远程请求
options.UseRemoteProcessor<YourRemoteProcessor>();
//你的步骤处理器执行器;当定义了工作流处理器该执行器会调用相应的处理器,
//需实现IStepProcessorExecutor接口或者继承自DefaultStepProcessorExecutor类重写 ExecuteAsync 方法
options.UseStepProcessorExecutor<YourStepProcessorExecutor>();
// 自定义表达式解析器,包含了工作流Actors参与者表达式、工作流步骤条件表达式,需实现 IExpressionParser 接口或者继承自 DefaultExpressionParser 类重写相关方法
//options.UseExpressionParser<YourExpressionParser>();
// 自定义工作流实例激活器,用于激活工作流实例(实例化)及工作流步骤处理记录;需实现 IWorkFlowActivator 接口,默认有个 DefaultWorkFlowActivator 实现
options.UseWorkFlowActivator<YourWorkFlowActivator>();
// 自定义工作流存储仓储服务,需实现 IWorkFlowRepository 接口,默认有个 DefaultWorkFlowRepository 实现,你也可以使用基于SqlSugar的Easy.WorkFlow.SqlSugar包
options.UseWorkFlowRepository<YourWorkFlowRepository>();
// 配置远程处理器配置选项
options.RemoteProcessorRequsetOptions = (configure) =>
{
// 远程请求的基础地址
configure.BaseAddress = new Uri("https://api.example.com/");
configure.DefaultRequestHeaders.Add("ApiKey", "your-api-key");
};
// 审批参与者表达式从工作流表单的解析配置
options.ParserOptions = (configure) =>
{
configure.UserIdKey = "userId"; // 指定表单中UserIdKey的key
configure.UserNameKey = "userName"; // 指定表单中UserNameKey的key
configure.IsIgnoreCase = true; // 是否忽略大小写
};
// 更多配置...
});
3. 创建工作流定义
1、手动创建工作流定义对象:DL_WF(不推荐)
// 从内存中创建工作流定义,建议使用Easy.WorkFlow.JsonBuilder从json中解析工作流定义
var workflowDefinition = new DL_WF
{
Name = "简单审批流程",
Description = "一个简单的两步审批流程示例",
Version = 1,
CreatedTime = DateTime.Now,
CreatedUserId = 1,
CreatedUserName = "Admin",
Steps = new List<DL_WFStep>
{
new DL_WFStep
{
Id = 1,
Number = 0, // 初始步骤
Name = "提交申请",
ActorType = ActorType.User,
Actors = new List<long> { 2 }, // 指定处理人ID
ActorNames = new List<string> { "审批人A" }
},
new DL_WFStep
{
Id = 2,
Number = 1,
Name = "经理审批",
ActorType = ActorType.User,
Actors = new List<long> { 3 }, // 指定处理人ID
ActorNames = new List<string> { "经理" }
}
}
};
// 构建工作流
var context = new WorkFlowBuilderContext<DL_WF>
{
Data = workflowDefinition
};
var result = await _workflowService.BuildAsync(context);
2、使用json构建工作流(推荐)
{
"id": 1001,
"name": "请假工作流",
"description": "请假审批",
"version": 1,
"steps": [
{
"id": 1,
"wfId": 1001,
"number": 0,
"name": "请假申请",
"description": "请假申请",
"when": null,
"processor": null,
"processorType": 1,
"processorContext": null,
"actors": null,
"actorNames": null,
"actorsExpression": null,
"actorType": 1,
"actionBtns": [
{
"name": "提交",
"type": 1,
"callback": null
}
],
"next": [
2
]
},
{
"id": 2,
"wfId": 1001,
"number": 1,
"name": "审批",
"description": "请假审批",
"when": null,
"processor": null,
"processorType": null,
"processorContext": null,
"actors": null,
"actorNames": null,
"actorsExpression": "[user]",
"actorType": 2,
"actionBtns": [
{
"name": "同意",
"type": 1,
"callback": null
},
{
"name": "拒绝",
"type": 2,
"callback": null
}
],
"next": null
}
],
"formName": "请假表单.json",
"createdTime": "2025-06-18",
"createdUserName": "cxj",
"createdUserId": 10001
}
// program.cs或startup.cs中注册JsonBuilder
services.AddWorkFlow()
.AddJsonBuilder(options =>
{
// 配置json工作流定义文件存放路径(可选),如使用从json字符串构建工作流则不需要配置
options.BasePath = Path.Combine(Directory.GetCurrentDirectory(), "json");
});
var builderContext = new WorkFlowBuilderContext<string>
{
SourceType = "json",
Source = "工作流定义.json", // 从json文件中构建工作流定义
};
// 构建工作流并存储到仓储
var result = await workflowService.BuildAsync(builderContext);
// 或者从json字符串构建工作流定义
var builderContext = new WorkFlowBuilderContext<string>
{
SourceType = "json",
Source = null,
Data="json字符串"
};
// 构建工作流并存储到仓储
var result = await workflowService.BuildAsync(builderContext);
响应/返回结果内容示例:
{
"code": 200,
"isSuccess": true,
"message": "构建成功",
"data": {
"id": 330182630739939328,
"name": "请假工作流",
"description": "请假审批",
"version": 1,
"steps": [
{
"id": 330182630752522240,
"parentId": 0,
"wfId": 330182630739939328,
"number": 0,
"name": "请假申请",
"description": "请假申请",
"when": null,
"processor": "api/text",
"processorType": 3,
"processorContext": "{\"method\":\"post\",\"content\":\"userid=[user.userid]&username=[user.username]\"}",
"actors": null,
"actorNames": null,
"actorsExpression": null,
"actorType": 1,
"actionBtns": [
{
"name": "提交",
"type": 1,
"callback": null
}
],
"next": [
{
"id": 330182630773493760,
"parentId": 330182630752522240,
"wfId": 330182630739939328,
"number": 1,
"name": "审批",
"description": "请假审批",
"when": null,
"processor": "Insert INTO WF_Text (Name,date) VALUES (@name,@date)",
"processorType": 1,
"processorContext": "name=[user.username]&date=[date]",
"actors": null,
"actorNames": null,
"actorsExpression": "[user]",
"actorType": 2,
"actionBtns": [
{
"name": "同意",
"type": 1,
"callback": null
},
{
"name": "拒绝",
"type": 2,
"callback": null
}
],
"next": null
}
]
},
{
"id": 330182630773493760,
"parentId": 330182630752522240,
"wfId": 330182630739939328,
"number": 1,
"name": "审批",
"description": "请假审批",
"when": null,
"processor": "Insert INTO WF_Text (Name,date) VALUES (@name,@date)",
"processorType": 1,
"processorContext": "name=[user.username]&date=[date]",
"actors": null,
"actorNames": null,
"actorsExpression": "[user]",
"actorType": 2,
"actionBtns": [
{
"name": "同意",
"type": 1,
"callback": null
},
{
"name": "拒绝",
"type": 2,
"callback": null
}
],
"next": null
}
],
"formName": "请假表单.json",
"createdTime": "2025-06-18T06:14:30.894Z",
"createdUserName": "cxj",
"createdUserId": 10001,
"updatedUserName": null,
"updatedUserId": null,
"updatedTime": null
}
}
返回结果包含的内容太多?请参照自定义工作流结果提供服务
4. 启动工作流
// 审批人信息,表示要从工作流表单中获取审批人信息
var approvalUser = new { UserId = 1002, UserName = "李四" };
// 创建启动请求
var request = new WorkFlowRequestContext
{
WorkFlowId = workflowId, // 工作流定义ID
UserId = 1002, // 发起人ID
UserName = "李四", // 发起人姓名
Data = new { Title = "请假申请", Days = 3, Reason = "个人事务",User=approvalUser } // 工作流表单数据,工作流步骤中可以通过表达式解析审批人信息("actorsExpression":"[user]")
};
// 启动工作流
var result = await _workflowService.StartAsync(request);
响应内容示例:
{
"code": 200,
"isSuccess": true,
"message": "执行成功",
"data": {
"wfInstanceId": 330183486885466112,
"stepId": 330182630773493760,
"wfProcessId": 330183486898049024,
"wfId": 330182630739939328,
"stepName": "审批",
"wfName": "请假工作流",
"actorIds": [
10002
],
"actorNames": [
"张三"
],
"authorId": 10001,
"authorName": "cxj",
"jsonData": "{\"user\":{\"userid\":10002,\"username\":\"张三\"},\"date\":\"2025-06-24\"}",
"processStatus": 1,
"processResult": "发起",
"processorExcutionResult": {
"isSuccess": true,
"message": "远程请求处理器执行成功",
"startTime": "2025-06-30T11:11:17.8632144+08:00",
"endTime": "2025-06-30T11:11:21.2433563+08:00",
"duration": "00:00:03.3801419"
},
"waitForProcessor": true
}
}
返回结果包含的内容太多?请参照自定义工作流结果提供服务
5. 运行工作流步骤(审批)
// 创建处理请求
var request = new WorkFlowRequestContext
{
WorkFlowInstanceId = instanceId, // 工作流实例ID
UserId = 10001, // 审批人ID
UserName = "张三", // 审批人姓名
ProcessingMessage = "同意请假申请", // 审批意见
ProcessingSuggestion = ProcessStatus.Approve //审批意见枚举,Approve:同意,Reject:拒绝
};
// 处理步骤
var result =await _workflowService.RunStepAsync(request);
响应内容示例:
{
"code": 200,
"isSuccess": true,
"message": "执行成功",
"data": {
"wfInstanceId": 330183486885466112,
"stepId": 330182630773493760,
"wfProcessId": 330183501666193408,
"wfId": 330182630739939328,
"stepName": "审批",
"wfName": "请假工作流",
"actorIds": null,
"actorNames": null,
"authorId": 10002,
"authorName": "张三",
"jsonData": "{\"user\":{\"userid\":10002,\"username\":\"张三\"},\"date\":\"2025-06-24\"}",
"processStatus": 1,
"processResult": "同意请假",
"processorExcutionResult": {
"isSuccess": true,
"message": "SQL处理器执行成功",
"startTime": "2025-06-30T11:12:57.1946878+08:00",
"endTime": "2025-06-30T11:12:57.205425+08:00",
"duration": "00:00:00.0107372"
},
"waitForProcessor": true
}
}
返回结果包含的内容太多?请参照自定义工作流结果提供服务
在Asp.NetCore web项目中建议搭配使用Easy.WorkFlow.AspNetCore包,集成了工作流核心流程的处理请求中间件,无需实现api接口 使用方式:app.UseWorkFlow();
扩展点
Easy.WorkFlow.Core 提供了多个扩展点,允许您自定义工作流行为:
- 自定义 ID 生成器:实现
IIdGenerator
接口 - 自定义工作流仓储:实现
IWorkFlowRepository
接口 - 自定义处理器:实现
IActionProcessor
、ISqlProcessor
或IRemoteProcessor
接口 - 自定义表达式解析器:实现
IExpressionParser
接口 - 自定义工作流构建器:实现
IWorkFlowBuilder
接口
存储适配器
Easy.WorkFlow.Core 支持通过实现 IWorkFlowRepository
接口来适配不同的存储方式。
官方提供了以下存储适配器:
- Easy.WorkFlow.SqlSugar:基于 SqlSugar ORM 的存储适配器,支持多种数据库
高级用法
使用步骤处理器
步骤处理器允许您在工作流步骤中执行自定义处理逻辑: 比如工作流步骤可能需要执行 SQL 语句、调用 Action 方法或执行远程API请求。
// SQL 处理器
var sqlStep = new DL_WFStep
{
// 其他属性...
ProcessorType = ProcessorType.SQL, //json定义:1表示SQL处理器,2表示Action处理器,3表示远程URL处理器
Processor = "UPDATE Test SET Name =@name WHERE Id = @id", // SQL 语句
ProcessorContext = "name=[user.username]&id=[id]" // 处理器上下文,从工作流表单数据中获取
};
// 远程处理器
var remoteStep = new DL_WFStep
{
// 其他属性...
ProcessorType = ProcessorType.URL,
Processor = "api/orders/approve",
ProcessorContext = "{\"method\":\"post\",\"content\":\"userid=[user.userid]&username=[user.username]\"}"
};
注意:远程处理器的上下文是一个对象
{
"method": "post", // 请求方法
"content": "userid=[user.userid]&username=[user.username]" // 请求体内容
}
使用参与者(审批人)表达式
从工作流表单中动态获取审批人或者你可以实现针对你项目的IExpressionParser。 默认的解析器使用工作流表单数据中的字段来解析参与者表达式,要求工作流表单属性值包含userid和username字段。
var dynamicActorStep = new DL_WFStep
{
// 其他属性...
ActorType = ActorType.Expression, //json定义:1表示用户,2表示表达式
ActorsExpression = "[user]" // 从工作流表单中动态获取[user]属性值对应的审批人
};
工作流表单数据示例:
{
"user": {
"userId": 1002,
"userName": "李四"
}"
}
ActorsExpression = "[user]"表示将从工作流表单数据中获取"user"属性对应的审批人信息。 你可以配置解析选项来指定工作流表单数据中参与者的字段名称。
// 审批参与者表达式从工作流表单的解析配置
options.ParserOptions = (configure) =>
{
configure.UserIdKey = "userId"; // 指定表单中UserIdKey的key
configure.UserNameKey = "userName"; // 指定表单中UserNameKey的key
configure.IsIgnoreCase = true; // 是否忽略大小写
};
如果需要实现诸如基于角色、部门领导等更复杂的表达式解析逻辑,可以自定义实现IExpressionParser
接口。
使用条件表达式
工作流步骤支持条件分支表达式,允许您根据工作流表单数据动态决定下一步执行的步骤。
当同一级别有多个步骤时,可以使用When
属性来定义条件表达式。
{
"id": 1002,
"name": "盖章申请",
"description": "盖章申请",
"version": 1,
"steps": [
{
"id": 1,
"wfId": 1002,
"number": 0,
"name": "盖章申请",
"description": "盖章申请",
"when": null,
"processor": null,
"processorType": null,
"actors": null,
"actorNames": null,
"actorsExpression": null,
"actorType": 1,
"actionBtns": [
{
"name": "提交",
"type": 1,
"callback": null
}
],
"next": [
2,
3
]
},
{
"id": 2,
"wfId": 1001,
"number": 1,
"name": "管理层审批",
"description": "管理层审批",
"when": "[type]==\"公章\" && [file]==\"方案\"",
"processor": null,
"processorType": null,
"actors": null,
"actorNames": null,
"actorsExpression": "[approval.users]",
"actorType": 2,
"actionBtns": [
{
"name": "同意",
"type": 1,
"callback": null
},
{
"name": "拒绝",
"type": 2,
"callback": null
}
],
"next": null
},
{
"id": 3,
"wfId": 1001,
"number": 1,
"name": "部门审批",
"description": "部门审批",
"when": "[type]==\"检测章\" && [file]==\"报告\"",
"processor": null,
"processorType": null,
"actors": null,
"actorNames": null,
"actorsExpression": "[approval.users]",
"actorType": 2,
"actionBtns": [
{
"name": "同意",
"type": 1,
"callback": null
},
{
"name": "拒绝",
"type": 2,
"callback": null
}
],
"next": null
}
],
"formName": "盖章申请表单.json",
"createdTime": "2025-06-18T06:14:30.894Z",
"createdUserName": "cxj",
"createdUserId": 10001
}
上述示例中,步骤2和步骤3属于同一级别的步骤,将根据工作流表单数据中的type
字段值及file
字段进行条件判断,决定执行哪个步骤。
条件表达式支持运算符如下:
==
:等于!=
:不等于&&
:与||
:或>
:大于<
:小于>=
:大于等于<=
:小于等于- 支持日期比较,如
[date] > '2025-01-01'
如需实现更复杂的条件表达式解析逻辑,可以自定义实现IExpressionParser
接口。
自定义工作流服务处理
您可以通过继承 WorkFlowHandler
类来实现自定义的工作流服务处理器。
重写 OnBuildingAsync
、OnBuildedAsync
、OnStartingAsync
、OnStartedAsync
、OnStepRunningAsync
、OnStepRunedAsync
等方法来添加自定义逻辑。
public class CustomWorkFlowHandler : WorkFlowHandler
{
// 在工作流启动前执行
public override Task OnStartingAsync(WorkFlowRequestContext request)
{
logger.LogInformation("我启动了一个工作流");
return Task.CompletedTask;
}
}
// 其他钩子方法同理
实现后无需注册,WorkFlow会自动扫描。
你也可以通过 options.UseWorkFlowHandler<YourWorkFlowHandler>()
显式注册。
自定义工作流结果提供服务
您可以通过实现 IWorkFlowResultProvider
接口来自定义工作流结果的返回处理。
public class CustomWorkFlowResultProvider : IWorkFlowResultProvider
{
/// <summary>
/// 工作流构建异常结果处理
/// </summary>
/// <typeparam name="T">构建源类型</typeparam>
/// <param name="exception">异常<see cref="WorkFlowException"/></param>
/// <param name="context">构建上下文</param>
/// <returns></returns>
public Task<WorkFlowResult> OnBuildException<T>(WorkFlowException exception, WorkFlowBuilderContext<T> context) where T : class
{
if (exception.ValidationException)
{
return Task.FromResult(WorkFlowResult.BadRequest(exception.Message)
.WithData(context));
}
return Task.FromResult(WorkFlowResult.Fail(exception.Message)
.WithData(context));
}
/// <summary>
/// 工作流构建成功结果处理
/// </summary>
/// <typeparam name="T">构建源类型</typeparam>
/// <param name="workFlow">构建完成的<see cref="WF"/></param>
/// <param name="context">构建上下文</param>
/// <returns></returns>
public Task<WorkFlowResult> OnBuildSuccess<T>(WF workFlow, WorkFlowBuilderContext<T> context) where T : class
{
return Task.FromResult(WorkFlowResult.Success("构建成功").WithData(workFlow));
}
/// <summary>
/// 工作流执行异常结果处理
/// </summary>
/// <param name="exception">异常<see cref="WorkFlowException"/></param>
/// <param name="context">工作流执行上下文</param>
/// <returns></returns>
public Task<WorkFlowResult> OnExcutionException(WorkFlowException exception, WorkFlowRequestContext context)
{
// 你的异常结果处理逻辑
}
/// <summary>
/// 工作流执行成功结果处理
/// </summary>
/// <param name="context">工作流执行上下文</param>
/// <returns></returns>
public Task<WorkFlowResult> OnExcutionSuccess(WorkFlowExcutionContext context)
{
// 你的成功结果处理逻辑
}
}
WorkFlowResult是一个规范化的统一结果包装类,包含了状态码、是否成功、消息、额外数据等信息。
默认情况下,WorkFlow会使用内置的结果提供服务来返回包含特定内容的WorkFlowResult结果。
实现IWorkFlowResultProvider接口后可以自定义WorkFlowResult返回的内容,你可以自定义状态码、消息、额外数据等。
IWorkFlowResultProvider实现后无需注册,WorkFlow会自动扫描。
你也可以通过 options.UseWorkFlowResultProvider<YourResultProvider>()
显式注册。
自定义工作流全局异常处理器
您可以通过实现 IWorkFlowExceptionHandler
接口来自定义工作流全局异常处理器。
public class CustomWorkFlowExceptionHandler : IWorkFlowExceptionHandler
{
public Task HandleExceptionAsync(Exception exception, string methodName, object context)
{
// 你的异常处理
// 比如记录日志、发送通知等
}
}
使用optipns.UseExceptionHandler<YourWorkFlowExceptionHandler>()注册即可。
注意事项
- Easy.WorkFlow.Core使用内存存储工作流相关的领域数据,实际项目中你应该使用数据库存储。为此请实现IWorkFlowRepository,或者使用现有的包。
- 在web项目中始终建议从json构建工作流,无需定义工作流对象。为此请使用Easy.WorkFlow.JsonBuilder包,或者实现你自己的Builder。
- 如需定义内置的强类型的工作流,可使用Easy.WorkFlow.FluentBuilder包,使用提供的Fluent api以编程的方法构建工作流。
许可证
Easy.WorkFlow.Core 使用 MIT 许可证。
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
- Microsoft.Extensions.Http (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
-
net6.0
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
- Microsoft.Extensions.Http (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
-
net7.0
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
- Microsoft.Extensions.Http (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
-
net8.0
- Microsoft.Extensions.DependencyInjection (>= 9.0.7)
- Microsoft.Extensions.Http (>= 9.0.7)
- System.Text.Json (>= 9.0.7)
-
net9.0
- Microsoft.Extensions.DependencyInjection (>= 9.0.7)
- Microsoft.Extensions.Http (>= 9.0.7)
- System.Text.Json (>= 9.0.7)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Easy.WorkFlow.Core:
Package | Downloads |
---|---|
Easy.WorkFlow.SqlSugar
基于SqlSugar ORM的Easy.WorkFlow工作流存储适配器。 |
|
Easy.WorkFlow.AspNetCore
工作流请求处理中间件包,提供对工作流的构建、启动、执行、停止、挂起、恢复等请求的处理。 |
|
Easy.WorkFlow.JsonBuilder
基于json的工作流构建包,支持从json文件或json字符串构建工作流。 |
|
Easy.WorkFlow.FluentBuilder
支持Fluent Api以编程的方式构建持久化的工作流 |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated | |
---|---|---|---|
2.3.14 | 120 | 9/4/2025 | |
2.3.13 | 192 | 8/29/2025 | |
2.3.12 | 237 | 8/7/2025 | |
2.3.11 | 259 | 7/29/2025 | |
2.3.10 | 178 | 7/28/2025 | |
2.3.9 | 520 | 7/24/2025 | |
2.3.8 | 872 | 7/24/2025 | |
2.3.7 | 927 | 7/22/2025 | |
2.3.6 | 945 | 7/22/2025 | |
2.3.5 | 685 | 7/20/2025 | |
2.3.4 | 665 | 7/15/2025 | |
2.3.3 | 666 | 7/14/2025 | |
2.3.2 | 605 | 7/14/2025 | |
2.3.1 | 627 | 7/11/2025 | |
2.3.0 | 694 | 7/9/2025 | |
2.2.2 | 639 | 6/30/2025 | |
2.2.1 | 639 | 6/30/2025 | |
2.2.0 | 599 | 6/28/2025 | |
2.1.0 | 636 | 6/26/2025 | |
2.0.0 | 640 | 6/24/2025 |