初试工作流workflowcore_workflowcore教程-程序员宅基地

技术标签: c#  

以前设计过ftp/sftp自动下载软件 ,用到了职责链模式,虽然工作没有问题,设计得很粗糙,最近发现工作流workflowcore,很是好用,可以当职责链模式用。

设计一个搜索硬盘上文件的小程序 ,玩一玩这个工作流,创建一个console项目,先nuget“Microsoft.Extensions.Logging”和“WorkflowCore”这二个包,创建Models文件夹,创建SearchFile模型。

namespace WorkflowTest2.Models
{
    internal class SearchFile
    {
        public string? FullName { get; set; }
        public bool IsDirectory { get; set; }
    }
}

再创建SearchFiles模型。

namespace WorkflowTest2.Models
{
    internal class SearchFiles
    {
        public string? SearchFolder { get; set; }

        public string? FolderContains { get; set; } = "";

        public List<SearchFile>? Files { get; set; }
    }
}

SearchFolder用于指定要搜索的文件夹,FolderContains用于指定要包含的文件夹字符串,Files用于装入搜索文件。

再创建Workflow文件夹,先创建Search_StepBody,Workflow有个很重要的概念:“步骤主体”,每个“步骤主体”都是一个黑盒,完成某一个功能,然后把它们组装起来。我设计的这个类,就要继承自StepBody。

using WorkflowCore.Interface;
using WorkflowCore.Models;
using WorkflowTest2.Models;

namespace WorkflowTest2.Workflow
{
    internal class Search_StepBody : StepBody
    {
        public string? SearchFolder { get; set; }
        public List<SearchFile>? SearchFiles { get; set; }
        public override ExecutionResult Run(IStepExecutionContext context)
        {
            if (SearchFolder is not null)
            {
                DirectoryInfo dir = new DirectoryInfo(SearchFolder);
                if (dir.Exists)
                {
                    SearchFiles = new List<SearchFile>();
                    //搜索文件夹
                    var query = dir.EnumerateDirectories().Where(d =>
                    {
                        return !((d.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);
                    });

                    foreach (var dirinfo in query)
                    {
                        SearchFiles.Add(new SearchFile { FullName = dirinfo.FullName, IsDirectory = true });
                    }
                    //搜索文件
                    var filesQuery = dir.EnumerateFiles().Where(f =>
                    {
                        return !((f.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);
                    });

                    foreach(var file in filesQuery)
                    {
                        SearchFiles.Add(new SearchFile { FullName = file.FullName, IsDirectory = false });
                    }
                }
            }
            return ExecutionResult.Next();
        }
    }
}

再设计一个stepbody,FolderContains_StepBody,以便更好的玩一玩。

using WorkflowCore.Interface;
using WorkflowCore.Models;
using WorkflowTest2.Models;

namespace WorkflowTest2.Workflow
{
    internal class FolderContains_StepBody : StepBody
    {
        public string? FolderContains { get; set; }

        public List<SearchFile>? InputFiles { get; set; }

        public List<SearchFile>? OutputFiles { get; set; }
        public override ExecutionResult Run(IStepExecutionContext context)
        {
            OutputFiles = new List<SearchFile>();
            //如果foldercontains字符串包含|,则分割成数组。
            if (FolderContains.Contains("|"))
            {
                string[] folders = FolderContains.Split('|');
                foreach (string folder in folders)
                {
                    foreach (var file in InputFiles)
                    {
                        if (file.IsDirectory && file.FullName.ToLower().Contains(folder))
                        {
                            OutputFiles.Add(file);
                        }
                    }
                }
            }
            else
            {
                if (String.IsNullOrWhiteSpace(FolderContains))
                {
                    OutputFiles = InputFiles;
                }
                else
                {
                    foreach (var file in InputFiles)
                    {
                        if (file.IsDirectory)
                        {
                            if(file.FullName.ToLower().Contains(FolderContains))
                            {
                                OutputFiles.Add(file);
                            }                            
                        }
                    }
                }
            }
            //文件夹处理完毕,添加文件
            foreach (var file in InputFiles)
            {
                if (!file.IsDirectory)
                {
                    var matchedFile = OutputFiles.Where(f => f.FullName == file.FullName).FirstOrDefault();

                    if (matchedFile is null)
                    {
                        OutputFiles.Add(file);
                    }
                }
            }
            //去重
            OutputFiles = OutputFiles.Distinct().ToList();
            
            return ExecutionResult.Next();
        }
    }
}

再设计SearchFilesWorkflow工作流,要引用IWorkflow<SearchFiles>,SearchFiles是我们设计要注入进去的数据。

using WorkflowCore.Interface;
using WorkflowTest2.Models;

namespace WorkflowTest2.Workflow
{
    internal class SearchFilesWorkflow : IWorkflow<SearchFiles>
    {
        public string Id => "Searchfiles";

        public int Version => 1;

        public void Build(IWorkflowBuilder<SearchFiles> builder)
        {
            builder
                .StartWith<Search_StepBody>()
                .Input(step => step.SearchFolder, data => data.SearchFolder)
                .Output(data => data.Files, step => step.SearchFiles)
                .Then<FolderContains_StepBody>()
                .Input(step => step.InputFiles, data => data.Files)
                .Input(step => step.FolderContains, data => data.FolderContains)
                .Output(data => data.Files, step => step.OutputFiles);
        }
    }
}

第一个Input是把SearchFiles里面的属性SearchFolder,输入进“步骤主体”Search_StepBody中的公共属性SearchFolder。Output是把在Search_StepBody里搜索到的文件从公共属性SearchFiles输出到自定义数据SearchFiles的公共属性Files中。

完成后再启动第二个“步骤主体”FolderContains_StepBody,再从自定义数据SearchFiles中,把Files输入到InputFiles,把FolderContains输入到步骤主体的FolderContains,步骤主体完成后再从公共属性OutputFiles中输出到Files中,最后,SearchFiles.Files里就是我们要的结果。

更改Program.cs文件内空如下

using Microsoft.Extensions.DependencyInjection;
using WorkflowCore.Interface;
using WorkflowTest2.Models;
using WorkflowTest2.Workflow;

namespace WorkflowTest2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var provider = ConfigureServices();
            var host = provider.GetService<IWorkflowHost>();
            host.RegisterWorkflow<SearchFilesWorkflow, SearchFiles>();
            var searchFiles = new SearchFiles() { SearchFolder = @"D:\Company", Files = new List<SearchFile>(),FolderContains="公司|奖金" };
            host.Start();
            host.StartWorkflow("Searchfiles", searchFiles);
            Console.WriteLine("等待结果...");
            Console.ReadLine();
            Console.WriteLine($"总项数: {searchFiles.Files.Count}");
            searchFiles.Files.ForEach(f => Console.WriteLine($"{f.FullName}  => {f.IsDirectory}"));
            Console.ReadLine();
            Console.WriteLine("结束..");
            host.Stop();
        }

        private static IServiceProvider ConfigureServices()
        {
            IServiceCollection services = new ServiceCollection();
            services.AddLogging();
            services.AddWorkflow();
            return services.BuildServiceProvider();
        }
    }
}

最后运行结果:

 

 一个好的项目,肯定会用上工作流的,这个是跨平台的工作流,轻量,易用。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/fdc2017/article/details/130435610

智能推荐

SaaS到底是什么,如何做?这份笔记讲明白了_saas如何开发-程序员宅基地

文章浏览阅读1.3k次。阅读本篇文章,您将可以了解:1、什么是SaaS;2、SaaS的商业模式;3、SaaS的技术架构;4、国内比较好的SaaS平台。_saas如何开发

摄像头接入_大华sdk frealdatacallback码流输出链接-程序员宅基地

文章浏览阅读1.5k次。摄像头接入目前摄像头直播的方案主要有以下几种方式: rtsp方式接入,只能实现视频预览 国标协议接入,实现比较复杂,需要多实现SIP服务器 通过netsdk获取到视频码流,推流到流媒体服务器,通过wsflv,flv,hls等流媒体协议播放,H265不支持 一、采用方案对比后最终采用了第三种方式,java使用jna的方式接入大华netsdk,获取到dav视频码流后去除大华头尾,拿到H264裸码流,通过javacv(对ffmpeg、opencv等库的封装)推送到.._大华sdk frealdatacallback码流输出链接

git-commit-amend踩坑_git remote-tracking 本地commit amend不了-程序员宅基地

文章浏览阅读1.4k次。因为改动比较小,所以我不想重建一个commit,于是我是用了git commit --amend命令,由于之前已经将该commit推送到远程仓库,导致修改后推送失败。百度后发现如果你的commit已经push到了远程仓库,那么使用--amend修改commit后,git push时一定要使用 --force-with-lease 参数来强制推送,否则就会报错。这是我自己推送失败的例子解决方式一、第一种使用后git commit --amend -m "修改Git学习(三)指令"注意:-m “._git remote-tracking 本地commit amend不了

AI实验1——八数码问题_人工智能实验八数码难题-程序员宅基地

文章浏览阅读2.5k次,点赞6次,收藏15次。AI实验1——八数码问题一、实验目的与要求实验目的:1 . 熟悉状态空间表示法;2.掌握深度优先、广度优先和等代价无信息搜索算法;3.掌握启发式函数设计,实现面向实际问题的A*搜索算法;二、实验内容与方法实验内容:利用无信息搜索算法实现八数码难题求解;设计启发式信息函数,利用A*搜索实现八数码难题求解;三、实验步骤与过程1,问题分析在八数码难题中,我们使用状态空间表示法,将八数码矩阵(即矩阵的状态)设置为一个节点类(Node),各个节点之间通过操作集(Operater)[‘U_人工智能实验八数码难题

【Js canvas实现是否透明,抠图等功能原理】_js-demo抠图-程序员宅基地

文章浏览阅读2.8k次,点赞4次,收藏11次。透明背景转jpg格式后变黑我们先看demo,您可以狠狠地点击这里:png图片是否含有透明像素JS检测demo如果是不含透明色的PNG图片,则会提示不含透明;如果是,则提示含透明,如下截图:是否背景透明的检测检测原理是借助canvas的getImageData()方法,关于此方法具体API和使用,可以参见““像素点信息获取”这里的详细介绍。_js-demo抠图

[附源码]java毕业设计高校班主任班级管理系统_高校班级管理系统-程序员宅基地

文章浏览阅读1.1k次。的需求进行调查研究,在对系统进行认真分析之后,得出开发整个系统的各项需求。为降低整个系统的复杂度,而使其更加便于修改,提高代码的可读性,我们会将系统模块化,模块间保持相对独立,且每个模块只完成一个子功能,并且与其他模块通过简单的接口链接,即高内聚低耦合原则,而使整个系统能够拥有一个高性能的结构,这边是系统概要设计最重要的目的。所以该系统的开发实现了最大的意义和价值,在系统完成后,利益是否大过于成本,是否能够达到预期效果,这些方面都要进行可行性分析,再通过分析之后,就可以决定是否开发此系统。_高校班级管理系统

随便推点

Linux SSH密码暴力破解技术及攻防实战_password top 1000-程序员宅基地

文章浏览阅读6k次,点赞8次,收藏55次。对于Linux操作系统来说,一般通过VNC、Teamviewer和SSH等工具来进行远程管理,SSH是 Secure Shell的缩写,由IETF的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和加粗样式其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。SSH客户端适..._password top 1000

html静态页面微信分享带缩略图,【荐】静态页面实现微信分享带缩略图、标题和描述...-程序员宅基地

文章浏览阅读1.2k次。这篇文章主要为大家详细介绍了【荐】静态页面实现微信分享带缩略图、标题和描述,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,有需要的朋友可以收藏方便以后借鉴。静态页面实现微信分享带缩略图、标题和描述,想法很现实,要想实现这样的功能这里就要用到大ajax技术,在这里361源码分享给大家。服务端文件jssdk.php代码:..._html分享链接加图片和描述不需要调用jssdk

VASP学习1入门知识_vaspwiki-程序员宅基地

文章浏览阅读5.9k次,点赞10次,收藏63次。大师兄科研实例使用方法:1从最基本的计算开始,通过示例讲解,结合一些脚本的使用,引导大家思考解决自己的问题。因此,在这本书的学习过程里,每一章节会对应一个例子,大家务必手动搭建模型,输入文件(切忌复制粘贴),然后进行计算,得到和大师兄一致的结果。为了引导大家主动浏览官网解决问题,很多都会采用VASP官网的例子。2如何学习本书,大师兄在学习程序时,受learn_python_the_hard_w..._vaspwiki

想说好多话_好多好多话-程序员宅基地

文章浏览阅读222次。以前觉得深圳好热,可是现在觉得沈阳的风好冷…每天不需要说太多的话,只要敲着喜欢的键盘,默默的清理掉禅道上的bug就好,这样的工作似乎是充实的,却总是少点什么,我也喜欢上了活在自己的小世界里,喜欢上了听歌,喜欢去刷微博,喜欢上去看那些心灵鸡汤和搞笑的博主,喜欢看看最近的陈伟霆是不是有帅了,偶尔碰到一条好玩的微博似乎会笑上一会儿,可能作为一个程序猿,真的比较枯燥叭,有时觉得孤单的像一条_好多好多话

简述计算机维修 维护的基本原则是什么,计算机硬件维护的四大原则-程序员宅基地

文章浏览阅读2.4k次。计算机硬件维护的四大原则近年来,随着社会经济的快速发展和计算机网络技术的广泛应用,如今计算机已经成为生产生活中不可或缺的必需品,随之而来就出现一些问题。下面是YJBYS小编为大家搜索整理的关于计算机硬件维护的四大原则,欢迎参考阅读,希望对大家有所帮助!想了解更多相关信息请持续关注我们应届毕业生培训网!对于计算机而言,主要包括硬件系统与软件系统两部分,其中硬件系统是软件系统功能得以实现的重要基础和前..._硬件维修的基本原则?

java有趣的技术分享ppt,java面试数据结构与算法高频考-程序员宅基地

文章浏览阅读736次。前言本文涵盖了阿里巴巴、腾讯、字节跳动、京东、华为等大厂的Java面试真题,不管你是要面试大厂还是普通的互联网公司,这些面试题对你肯定是有帮助的,毕竟大厂一定是行业的发展方向标杆,很多公司的面试官同样会研究大厂的面试题。与此同时,今年算法面试一定是会被问的,而算法不是光靠背面试题就有用的,它是需要数学逻辑思维的,因此,小编会在文末为大家准备一份非常优质的算法学习手册,重点在于学习思维方法,话不多说,直接开始上精选的大厂面试真题!在校生如果你是在校生,你应该趁着在学校的时间夯实基础(比如计算机系统、_java有趣的技术分享

推荐文章

热门文章

相关标签