NET Core用の超軽量ワークフローエンジン:Workflow-Core

NET Core用の超軽量ワークフローエンジン:Workflow-Core

ワークフローについて聞いたが、何ができるかわからなかった。

最后更新 2023/02/06 22:36
Jimmy.Tang
预计阅读 6 分钟
分类
.NET
标签
.NET C#

ウェブマスターはこの技術を仕事で使用するので、この記事を転載して、ワークフローを理解し、それで何ができるかを学びます。

本文は以下のとおり。


最近、OA関連のウェブサイト開発をしたいと思っていて、ワークフローについて聞いていて、ワークフロー Foundation 4.0を断続的に学んだことがありますが、何ができるのかわかりません。

しかし、まだ特定の状況ではワークフローが適用されるべきだと感じ、答えはありませんが、オンラインで検索し、ワークフローコアのものを見つけ、非常に興味深いと感じたので、立ち止まって考えて、皆さんと共有しました。

プロフィール:プロフィール

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 那样有图形化的操作界面,但感觉代码比较干净。

  • Net Standard 2.0の紹介

开始的时候不了解什么是.Net Standard 2.0,这篇文章讲得比较清楚,.Net Standard 与 .NET Framework 关系,还有这个.NET Core 2.0 是您的最好选择吗,原来微软为了统一.Net 的各种平台,出了一个.Net Standard 标准库,基于这个库开发的,可以应用于.net framework 4.6.1 以上版本,也可以应用于.net core 2.0 以上。

関連する内容を理解したら、直接説明を開き、例に従ってください。

例1の例

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

可能由于版本的关系,还需要另外安装两个包:Microsoft.Extensions.LoggingMicrosoft.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();
    }
}
  1. ワークフローを構築し、IWorkflowインターフェイスを実装します。各ワークフローにはIDとバージョンがあり、ワークフローを識別し、HelloWorkflowは2つの方法で構築されます。
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>();
    }
}
  1. ワークフローを実行する準備ができました。最初のステップは、もちろんサービスを構築する必要があります。ワークフローコアは、インジェクション名前空間のService Collectionを通じてワークフロー関連サービスを追加します。パラメータ付きのStepBodyの場合、最初にサービスの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;
}

次に、ワークフローホストを起動し、ワークフローを一度起動し、フォーム全体のコードを貼り付けるので、より明確です。

using Microsoft.Extensions.DependencyInjection;
using System.Windows;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Debug;
using WorkflowCore.Interface;

namespace WorkflowTest;

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の簡単な例が完成し、全体的に非常にシンプルで明確です。

この記事は転載から。

著者:ジミー·タン

前の記事:. NET Core用の超軽量ワークフローエンジン:Workflow-Core

原文へのリンク:https//www.cnblogs.com/keep-study-to-die/p/12001408.html

站长注:文中代码其实引用了不少包,但原文未说全,站长测试时已将包补全,测试代码见:https://github.com/dotnet9/TerminalMACS.ManagerForWPF/tree/master/src/Demo/WorkflowTest

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2026/04/22

バージョン別の. NETサポート状況(250 7 0 7更新)

仮想マシンとテストマシンを使用して、各バージョンのオペレーティングシステムの. NETサポートをテストします。オペレーティングシステムのインストール後、対応するランタイムを測定し、スターダストエージェントをパスとして実行できます。

继续阅读
同分类 / 同标签 2026/02/07

AOTの使用経験

プロジェクトの最初から、新しい機能が追加されたり、新しい構文が使用されたりするたびに、AOTリリーステストを行うという良い習慣を身につける必要があります。

继续阅读