最近想做一個(gè)OA相關(guān)的網(wǎng)站開發(fā),一直都聽說有workflow的東西,之前也斷斷續(xù)續(xù)學(xué)習(xí)過 Workflow Foundation 4.0,還是沒有搞明白到底能夠用它做什么
但還是覺得workflow在某種情形下應(yīng)該可以適用,雖然還沒有答案,網(wǎng)上搜樓了一通,發(fā)現(xiàn)一個(gè)workflow-core的東西,覺得挺有意思,遂停下來,琢磨一下,現(xiàn)分享與大家。
* 簡介
workflow core的GitHub主頁
https://github.com/danielgerlag/workflow-core
如主頁上介紹的,workflow core作為一個(gè)輕量級(jí)workflow引擎,可以嵌入到項(xiàng)目中,其底層是用.NET standard 2.0開發(fā),可以用來追蹤長時(shí)間運(yùn)行的任務(wù)狀態(tài),功能也比較強(qiáng)大,支持插件形式持久化,和多節(jié)點(diǎn)并行處理,貌似很牛。并且目前有給一個(gè) Conductor 項(xiàng)目,就是使用workflow core作為內(nèi)核的workflow服務(wù)器(原來運(yùn)行workflow,需要單獨(dú)的一個(gè)服務(wù)器啊),Conductor這里就不展開了。workflow core支持fluent語法,寫起來也非常美觀,雖然沒有WF那樣有圖形化的操作界面,但感覺代碼比較干凈。
* 示例1
新建一個(gè)項(xiàng)目,指明使用.net framework 4.6.1以上,新建項(xiàng)目后,在Package Manager Console中,安裝workflow core:Install-Package WorkflowCore,安裝這個(gè)包會(huì)默認(rèn)安裝一系列的依賴包
可能由于版本的關(guān)系,還需要另外安裝兩個(gè)包:Microsoft.Extensions.Logging 和 Microsoft.Extensions.Logging.Debug。這樣就可以按照Sample 01開始編寫代碼了
Sample01是一個(gè)helloworld,包含了幾部分內(nèi)容:
1. 構(gòu)建StepBody,就是workflow中需要執(zhí)行的內(nèi)容,每個(gè)類繼承自StepBody這個(gè)虛擬類,重載ExecutionResult Run(IStepExecutionContext context),這個(gè)函數(shù)中完成所需的工作
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. 構(gòu)建workflow,實(shí)現(xiàn)IWorkflow接口,每個(gè)workflow有一個(gè)Id和一個(gè)Version,標(biāo)明這個(gè)workflow的身份,這里通過兩種方法構(gòu)建了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. 萬事俱備,準(zhǔn)備讓workflow運(yùn)行起來。第一步當(dāng)然是需要搭建service,Workflow Core通過Injection命名空間的ServiceCollection添加了Workflow相關(guān)的服務(wù),對(duì)于有參數(shù)的StepBody,需要先通過service的AddTransient函數(shù)注冊(cè),這樣才能正確的構(gòu)造對(duì)象
/// <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")); // 這些個(gè)構(gòu)造函數(shù)帶參數(shù)的,需要添加到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; }
接下來,啟動(dòng)workflow 主機(jī),并啟動(dòng)一次workflow,將整個(gè)窗體代碼貼一下,這樣比較清晰
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啟動(dòng)了,不能再次啟動(dòng),但沒有判斷方法 if (!serviceStarted) { host.Start(); serviceStarted = true; } // 啟動(dòng)workflow工作流 host.StartWorkflow("HelloWorkflow", 1, data: null); // //host.StartWorkflow("HelloWorkflow");//, 2, data: null, 默認(rèn)會(huì)啟用版本高的 } 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")); // 這些個(gè)構(gòu)造函數(shù)帶參數(shù)的,需要添加到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(); } }}
就這樣一個(gè)簡單的Workflow Core例子就完成了,總體來說,還是很簡單,清晰的。
出處:
https://www.cnblogs.com/keep-study-to-die/p/12001408.html
版權(quán)申明:本文來源于網(wǎng)友收集或網(wǎng)友投稿,僅供學(xué)習(xí)交流之用,如果有侵權(quán),請(qǐng)轉(zhuǎn)告版主或者留言,本人立即刪除。