您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > .NET

一个适合于.NET Core的超轻量级工作流引擎:Workflow-Core

时间:2022-08-07 15:47:32  来源:  作者:IT狂人日记

最近想做一个OA相关的网站开发,一直都听说有workflow的东西,之前也断断续续学习过 Workflow Foundation 4.0,还是没有搞明白到底能够用它做什么

但还是觉得workflow在某种情形下应该可以适用,虽然还没有答案,网上搜楼了一通,发现一个workflow-core的东西,觉得挺有意思,遂停下来,琢磨一下,现分享与大家。

* 简介

workflow core的Github主页

https://github.com/danielgerlag/workflow-core

如主页上介绍的,workflow core作为一个轻量级workflow引擎,可以嵌入到项目中,其底层是用.NET standard 2.0开发,可以用来追踪长时间运行的任务状态,功能也比较强大,支持插件形式持久化,和多节点并行处理,貌似很牛。并且目前有给一个 Conductor 项目,就是使用workflow core作为内核的workflow服务器(原来运行workflow,需要单独的一个服务器啊),Conductor这里就不展开了。workflow core支持fluent语法,写起来也非常美观,虽然没有WF那样有图形化的操作界面,但感觉代码比较干净。

* 示例1

新建一个项目,指明使用.net framework 4.6.1以上,新建项目后,在Package Manager Console中,安装workflow core:Install-Package WorkflowCore,安装这个包会默认安装一系列的依赖包

可能由于版本的关系,还需要另外安装两个包:Microsoft.Extensions.Logging 和 Microsoft.Extensions.Logging.Debug。这样就可以按照Sample 01开始编写代码了

 

Sample01是一个helloworld,包含了几部分内容:

1. 构建StepBody,就是workflow中需要执行的内容,每个类继承自StepBody这个虚拟类,重载ExecutionResult Run(IStepExecutionContext context),这个函数中完成所需的工作

public class HelloWorld : StepBody    {        private ILogger logger;        public HelloWorld(ILoggerFactory loggerFactory)        {            logger = loggerFactory.CreateLogger<HelloWorld>();        }        public override ExecutionResult Run(IStepExecutionContext context)        {            Console.WriteLine("Hello world, workflow");            logger.LogInformation("Helloworld workflow");            return ExecutionResult.Next();        }    }    public class GoodbyeWorld : StepBody    {        private ILogger logger;        public GoodbyeWorld(ILoggerFactory loggerFactory)        {            logger = loggerFactory.CreateLogger<GoodbyeWorld>();        }        public override ExecutionResult Run(IStepExecutionContext context)        {            Console.WriteLine("Workflow, Goodbye");            logger.LogInformation("Goodbye workflow");            return ExecutionResult.Next();        }    }    public class SleepStep : StepBody    {        private ILogger logger;        public SleepStep(ILoggerFactory loggerFactory)        {            logger = loggerFactory.CreateLogger("SleepStep");        }        public override ExecutionResult Run(IStepExecutionContext context)        {            Thread.Sleep(1000);            logger.LogInformation("Sleeped");            return ExecutionResult.Next();        }    }

2. 构建workflow,实现IWorkflow接口,每个workflow有一个Id和一个Version,标明这个workflow的身份,这里通过两种方法构建了HelloWorkflow

   public class HelloWorkflow : IWorkflow    {        public string Id => "HelloWorkflow";        public int Version => 1;        public void Build(IWorkflowBuilder<object> builder)        {            builder.StartWith(context =>            {                Console.WriteLine("Hello world");                return ExecutionResult.Next();            })            .Then(context =>            {                Thread.Sleep(500);                Console.WriteLine("sleeped");                return ExecutionResult.Next();            })            .Then(context =>            {                Console.WriteLine("Goodbye world");                return ExecutionResult.Next();            });        }    }    public class HelloWorkflow2 : IWorkflow    {        public string Id => "HelloWorkflow";        public int Version => 2;        public void Build(IWorkflowBuilder<object> builder)        {            builder.StartWith<HelloWorld>()                .Then<SleepStep>()                .Then<GoodbyeWorld>();        }    }

3. 万事俱备,准备让workflow运行起来。第一步当然是需要搭建service,Workflow Core通过Injection命名空间的ServiceCollection添加了Workflow相关的服务,对于有参数的StepBody,需要先通过service的AddTransient函数注册,这样才能正确的构造对象

/// <summary> /// 配置workflow /// </summary> /// <returns></returns> private IServiceProvider ConfigureServices() {     //setup dependency injection     IServiceCollection services = new ServiceCollection();     services.AddLogging();     services.AddWorkflow();     //services.AddWorkflow(x => x.UseMongoDB(@"mongodb://localhost:27017", "workflow"));     // 这些个构造函数带参数的,需要添加到transient中     services.AddTransient<HelloWorld>();     services.AddTransient<GoodbyeWorld>();     services.AddTransient<SleepStep>();     var serviceProvider = services.BuildServiceProvider();     //config logging     var loggerFactory = serviceProvider.GetService<ILoggerFactory>();     loggerFactory.AddProvider(new DebugLoggerProvider());     return serviceProvider; }

接下来,启动workflow 主机,并启动一次workflow,将整个窗体代码贴一下,这样比较清晰

using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;using Microsoft.Extensions.Logging.Console;using Microsoft.Extensions.Logging.Debug;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using WorkflowCore.Interface;using WorkflowCore.Services;using WorkFlowCoreTest.MyWorkflow;namespace WorkFlowCoreTest{    /// <summary>    /// Interaction logic for MAInWindow.xaml    /// </summary>    public partial class MainWindow : Window    {        IServiceProvider serviceProvider = null;        bool serviceStarted = false;        public MainWindow()        {            InitializeComponent();        }        private void StartWorkflow()        {            if (serviceProvider == null)            {                serviceProvider = ConfigureServices();                var host1 = serviceProvider.GetService<IWorkflowHost>();                host1.RegisterWorkflow<HelloWorkflow>();                host1.RegisterWorkflow<HelloWorkflow2>();            }            var host = serviceProvider.GetService<IWorkflowHost>();            var wd = host.Registry.GetDefinition("HelloWorkflow");            // 如果host启动了,不能再次启动,但没有判断方法            if (!serviceStarted)            {                host.Start();                serviceStarted = true;            }            // 启动workflow工作流            host.StartWorkflow("HelloWorkflow", 1, data: null); //            //host.StartWorkflow("HelloWorkflow");//, 2, data: null, 默认会启用版本高的        }        private void StopWorkflow()        {            var host = serviceProvider.GetService<IWorkflowHost>();            host.Stop();            serviceStarted = false;        }        /// <summary>        /// 配置workflow        /// </summary>        /// <returns></returns>        private IServiceProvider ConfigureServices()        {            //setup dependency injection            IServiceCollection services = new ServiceCollection();            services.AddLogging();            services.AddWorkflow();            //services.AddWorkflow(x => x.UseMongoDB(@"mongodb://localhost:27017", "workflow"));            // 这些个构造函数带参数的,需要添加到transient中            services.AddTransient<HelloWorld>();            services.AddTransient<GoodbyeWorld>();            services.AddTransient<SleepStep>();            var serviceProvider = services.BuildServiceProvider();            //config logging            var loggerFactory = serviceProvider.GetService<ILoggerFactory>();            loggerFactory.AddProvider(new DebugLoggerProvider());            return serviceProvider;        }        private void startButton_Click(object sender, RoutedEventArgs e)        {            StartWorkflow();        }        private void stopButton_Click(object sender, RoutedEventArgs e)        {            StopWorkflow();        }    }}

就这样一个简单的Workflow Core例子就完成了,总体来说,还是很简单,清晰的。

 

出处:

https://www.cnblogs.com/keep-study-to-die/p/12001408.html

 

版权申明:本文来源于网友收集或网友投稿,仅供学习交流之用,如果有侵权,请转告版主或者留言,本人立即删除。



Tags:Workflow-Core   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
一个适合于.NET Core的超轻量级工作流引擎:Workflow-Core
最近想做一个OA相关的网站开发,一直都听说有workflow的东西,之前也断断续续学习过 Workflow Foundation 4.0,还是没有搞明白到底能够用它做什么但还是觉得workflow在某种情形下...【详细内容】
2022-08-07  Search: Workflow-Core  点击:(1137)  评论:(0)  加入收藏
▌简易百科推荐
.Net开发中十种常见的内存错误以及相应的解决方案
在.Net开发中,为内存管理方面提供了许多便利,但仍然存在一些常见的错误和陷阱。这些错误可能导致内存泄漏、性能下降、异常抛出等问题,严重影响应用程序的稳定性和性能。在软件...【详细内容】
2024-03-26  小乖兽技术  今日头条  Tags:.Net   点击:(18)  评论:(0)  加入收藏
.NET配置文件大揭秘:轻松读取JSON、XML、INI和环境变量
概述:.NET中的IConfiguration接口提供了一种多源读取配置信息的灵活机制,包括JSON、XML、INI文件和环境变量。通过示例,清晰演示了从这些不同源中读取配置的方法,使配置获取变得...【详细内容】
2023-12-28  架构师老卢  今日头条  Tags:.NET   点击:(94)  评论:(0)  加入收藏
.Net开发都应当掌握的泛型基础知识集合
在C#编程语言中,泛型是一项非常强大和重要的功能。它允许我们编写更加灵活和通用的代码,同时提高代码的可重用性和性能。本文将介绍C#泛型的一些关键知识点,帮助读者理解和应用...【详细内容】
2023-12-25  小乖兽技术  今日头条  Tags:.Net   点击:(128)  评论:(0)  加入收藏
作为 .NET 开发人员,我为什么开始使用 Python?
作者 | Alex Maher编译 | 小欧作为一名 .NET 开发人员,很长一段时间以来,我一直关注 C# 和 .NET 的出色工具和功能。但我最近开始使用 Python,感觉非常棒。这里申明一点,这篇文...【详细内容】
2023-12-25    51CTO  Tags:.NET   点击:(147)  评论:(0)  加入收藏
.NET Core 3.1 升级到 .NET 8,看看都有哪些变化
.NET Core 3.1 已经用了很长一段时间,其实在 2022 年的年底微软已经不提供支持了,后面的一个 LTS 版本 .NET 6 也会在 2024 年 11 月终止支持,所以直接升级到 .NET 8 是最好的...【详细内容】
2023-12-08  不止dotNET  微信公众号  Tags:.NET   点击:(196)  评论:(0)  加入收藏
.NET Core的中间件来对Web API进行流量限制实现方法
在.NET Core中,我们可以使用ASP.NET Core的中间件来对Web API进行流量限制。ASP.NET Core提供了一个名为RateLimit的开源库,可以方便地实现流量限制功能。下面将详细介绍如何...【详细内容】
2023-12-06  架构师老卢  今日头条  Tags:.NET   点击:(179)  评论:(0)  加入收藏
微软官方出品微服务架构:十个.Net开源项目
1、一个高性能类型安全的.NET枚举实用开源库Enums.NET是一个.NET枚举实用程序库,专注于为枚举提供丰富的操作方法。它支持.NET Framework和.Net Core。它主要优点表现在类型...【详细内容】
2023-12-06  编程乐趣  今日头条  Tags:.Net   点击:(137)  评论:(0)  加入收藏
.NET开源的处理分布式事务的解决方案
前言在分布式系统中,由于各个系统服务之间的独立性和网络通信的不确定性,要确保跨系统的事务操作的最终一致性是一项重大的挑战。今天给大家推荐一个.NET开源的处理分布式事务...【详细内容】
2023-11-30  追逐时光者  微信公众号  Tags:.NET   点击:(173)  评论:(0)  加入收藏
深入 .NET 异步编程:Task 与 ValueTask 的区别与选择
在 .NET 中,Task 和 ValueTask 都是用于表示异步操作的类型,但它们有一些重要的区别。TaskTask 是最常见的表示异步操作的类型。它通常用于表示耗时的、异步的操作,比如从文件...【详细内容】
2023-11-26  架构师老卢  微信公众号  Tags: .NET   点击:(191)  评论:(0)  加入收藏
.NET字符串存储:解析常量与动态字符串,深入了解内存机制
在 .NET 中,字符串是不可变的,这意味着一旦创建,字符串的内容就不能被修改。字符串在内存中以不同的方式存储,具体取决于它是常量字符串还是动态创建的字符串。常量字符串常量字...【详细内容】
2023-11-25  架构师老卢  微信公众号  Tags:.NET   点击:(206)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条