有阿里云服务器 怎么做网站,合理规划网站,dede怎么做双语网站,北京网站建设公司知乎近期工作上有一个工作流的开发需求#xff0c;自己基于面向对象和职责链模式捣鼓了一套小框架#xff0c;后来在github上发现一个轻量级的工作流引擎轮子#xff1a;Workflow-Core#xff0c;看完其wiki之后决定放弃之前自己造的轮子#xff0c;使用这个开源项目来改造自己基于面向对象和职责链模式捣鼓了一套小框架后来在github上发现一个轻量级的工作流引擎轮子Workflow-Core看完其wiki之后决定放弃之前自己造的轮子使用这个开源项目来改造也就有了这一篇博文。01—关于Workflow-Core Workflow-Core是一个基于.NET Standard的轻量级工作流引擎其GitHub地址为https://github.com/danielgerlag/workflow-core目前有超过1200个star。它提供了FluentAPI、多任务、持久化以及并行处理的功能适合于小型工作流、责任链的需求开发。 由于Workflow-Core支持工作流长期运行因此Workflow-Core支持以下多种数据源格式的持久化可以通过安装不同的Provider包来实现对应的持久化内存默认提供用于测试和开发MongoDBMS SQL ServerMySqlSqliteRedisPostgreSQL 立刻上手把Nuget上安装一把目前最新版本2.0.0PM Install-Package WorkflowCore02—Workflow-Core 基础使用1、Hello World这里创建了一个.NET Core控制台应用程序快速演示第一个Workflow-Core的Hello World展示如何开始一个Workflow 1定义一个实现IWorkflow接口的Workflow public class HelloWorldWorkflow : IWorkflow { public string Id HelloWorld; public int Version 1; public void Build(IWorkflowBuilderobject builder) { builder .StartWithHelloWorld() .ThenActiveWorld() .ThenGoodbyeWorld(); } } 这里定义了一个HelloWorldWorkflow其版本号为1它有3个步骤HelloWorld、ActiveWorld和GoodbyeWorld会依次执行。 2定义三个继承自StepBody类的步骤类 public class HelloWorld : StepBody { public override ExecutionResult Run(IStepExecutionContext context) { Console.WriteLine(Hello World!); return ExecutionResult.Next(); } } public class ActiveWorld : StepBody { public override ExecutionResult Run(IStepExecutionContext context) { Console.WriteLine(I am activing in the World!); return ExecutionResult.Next(); } } public class GoodbyeWorld : StepBody { public override ExecutionResult Run(IStepExecutionContext context) { Console.WriteLine(Goodbye World!); return ExecutionResult.Next(); } } 3ServiceCollection中注入Workflow-Core相关组件 private static IServiceProvider ConfigureServices() { IServiceCollection services new ServiceCollection(); services.AddLogging(); // WorkflowCore需要用到logging service services.AddWorkflow(); var serviceProvider services.BuildServiceProvider(); return serviceProvider; } 4在Program.cs的Main方法中获取到注入的host并执行工作流 public static void Main(string[] args) { var serviceProvider ConfigureServices(); var host serviceProvider.GetServiceIWorkflowHost(); host.RegisterWorkflowHelloWorldWorkflow(); host.Start(); // Demo1:Hello World host.StartWorkflow(HelloWorld); Console.ReadKey(); host.Stop(); } 这里传入的是Workflow的IdWorkflow-Core会根据Id去自动匹配最新版本的对应Workflow运行结果如下 2、无处不在的If 在工作流处理中往往会有很多的条件判断那么在Workflow-Core中也提供了直接的If功能如下面这个IfStatementWorkflow所示public class IfStatementWorkflow : IWorkflowMyData { public string Id if-sample; public int Version 1; public void Build(IWorkflowBuilderMyData builder) { builder .StartWithSayHello() .If(data data.Counter 3).Do(then then .StartWithPrintMessage() .Input(step step.Message, data Outcome is less than 3) ) .If(data data.Counter 5).Do(then then .StartWithPrintMessage() .Input(step step.Message, data Outcome is less than 5) ) .ThenSayGoodbye(); } } 这个传递进来的MyData的定义如下public class MyData { public int Counter { get; set; } } 当传递进来的MyData的Counter属性3 或 5时会有不同的分支进行逻辑的处理。3、MySQL持久化支持 想要将工作流配置持久化到MySQL只需以下两步 1通过Nuget安装MySQL Provider包PM Install-Package WorkflowCore.Persistence.MySQL 2注入到ServiceCollectionservices.AddWorkflow(x x.UseMySQL(Server127.0.0.1;Databaseworkflow;Userroot;Passwordpassword;, true, true)); 一旦启动你就会发现Workflow-Core自动帮你创建了很多表用于持久化工作流配置和实例。 4、计划任务和循环任务 Workflow-Core还继承了计划任务和循环任务的功能 1计划任务比如在工作流步骤中设置一个延迟5分钟执行的计划任务builder .StartWith(context Console.WriteLine(Hello)) .Schedule(data TimeSpan.FromSeconds(5)).Do(schedule schedule .StartWith(context Console.WriteLine(Doing scheduled tasks)) ) .Then(context Console.WriteLine(Doing normal tasks)); 2循环任务比如在工作流步骤中设置一个延迟5分钟进行的循环任务知道Counter 5才结束builder .StartWith(context Console.WriteLine(Hello)) .Recur(data TimeSpan.FromSeconds(5), data data.Counter 5).Do(recur recur .StartWith(context Console.WriteLine(Doing recurring task)) ) .Then(context Console.WriteLine(Carry on));5、Saga支持 了解分布式事务方案的童鞋应该都知道Saga在Workflow-Core中也有支持这是一个十分有用的功能 1比如在创建一个客户信息之后将其推送到Salesforce和ERP如果推送过程中发生了错误那么就通过重试进行补偿并且重试有时间间隔。builder .StartWithCreateCustomer() .ThenPushToSalesforce() .OnError(WorkflowErrorHandling.Retry, TimeSpan.FromMinutes(10)) .ThenPushToERP() .OnError(WorkflowErrorHandling.Retry, TimeSpan.FromMinutes(10)); 2又比如当Task2发生异常时Workflow-Core会帮助执行UndoTask2 和 UndoTask1 帮你回滚数据以恢复状态。builder .StartWithLogStart() .Saga(saga saga .StartWithTask1() .CompensateWithUndoTask1() .ThenTask2() .CompensateWithUndoTask2() .ThenTask3() .CompensateWithUndoTask3() ) .OnError(Models.WorkflowErrorHandling.Retry, TimeSpan.FromMinutes(10)) .ThenLogEnd(); 更多Saga示例请参考https://github.com/danielgerlag/workflow-core/tree/master/src/samples/WorkflowCore.Sample1703—ASP.NET Core中使用Workflow-Core1、注入与初始化 1注入使用AddWorkflow()扩展方法 public void ConfigureServices(IServiceCollection services) { services.AddWorkflow(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } 2初始化 public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ....... app.UseWorkflow(); } 扩展方法如下 public static class ConfigureExtensions { public static IApplicationBuilder UseWorkflow(this IApplicationBuilder app) { var host app.ApplicationServices.GetServiceIWorkflowHost(); host.RegisterWorkflowEdcWorkflow(); host.RegisterWorkflowEdcDataWorkflow, EdcData(); host.Start(); var appLifetime app.ApplicationServices.GetServiceIApplicationLifetime(); appLifetime.ApplicationStopping.Register(() { host.Stop(); }); return app; } } 这里需要注意的就是将你要用到的所有Workflow都事先进行Register注册。 在你想要用到的地方无论是Controller还是Service通过依赖注入获取到Host并使用它 [Route(api/[controller])] [ApiController] public class ValuesController : ControllerBase { private IWorkflowController _workflowService; public ValuesController(IWorkflowController workflowService) { _workflowService workflowService; } // GET api/values [HttpGet] public async TaskIEnumerablestring Get() { await _workflowService.StartWorkflow(EdcWorkflow); return new string[] { EdcWorkflow v1 }; } // GET api/values/5 [HttpGet({id})] public async Taskstring Get(int id) { await _workflowService.StartWorkflow(EdcDataWorkflow, new EdcData() { Id id }); return EdcDataWorkflow v1; } } 这两个Workflow的定义如下 public class EdcWorkflow : IWorkflow { public string Id EdcWorkflow; public int Version 1; public void Build(IWorkflowBuilderobject builder) { builder .StartWithHelloWorld() .ThenGoodbyeWorld(); } } public class EdcDataWorkflow : IWorkflowEdcData { public string Id EdcDataWorkflow; public int Version 1; public void Build(IWorkflowBuilderEdcData builder) { builder .StartWithHelloWorld() .If(data data.Id 3).Do(then then .StartWithPrintMessage() .Input(step step.Message, data Passed Id is less than 3) ) .If(data data.Id 5).Do(then then .StartWithPrintMessage() .Input(step step.Message, data Passed Id is less than 5) ) .ThenGoodbyeWorld(); } } 示例结果很简单 1api/values 2api/values/1 04—小结Workflow-Core是一个适合.NET Core的优秀的轻量级工作流引擎对于小型工作流和责任链类型的需求开发很适合可以节约大量时间避免重复造轮子将时间主要花在业务逻辑上面。当然这里演示的示例只是众多功能特性中的一小部分我只是选取了我用到的部分而已大家有兴趣的话可以去GitHub上先给个star再仔细研究其wiki文档应用到自己的项目中去。恰童鞋骚年风华不再正茂仍想挥斥方遒点个在看少个bug ?