如何实现简单的工作流管道流畅的api方法链接?

时间:2016-12-19 14:35:09

标签: c# workflow fluent method-chaining

我想找到一个关于如何实现此示例业务工作流的良好设计模式。我没有使用一个巨大的单片程序式方法调用,而是想我想使用流畅的方法链接 - 基本上,一个简单的工作流管道,而不使用其中一个工作流或BPM框架。关于最佳实践的建议,也许是一种已知的设计模式?

我的例子

  1. 获取配置/用户首选项
  2. 验证配置/首选项
  3. 查找/标准化其他配置/首选项
  4. 获取报告1(以上输入)
  5. 获取报告2等
  6. 电子邮件报告
  7. 输入/用户首选项会导致很多if / else逻辑,所以我不想让我的方法必须包含我所有的if / else逻辑,以查看每个步骤是否成功,并处理。 (即我不想要)

       myOutput1 = CallMethod1(param1, param2, our errorMsg)
       if (error)
       { // do something, then break }
    
       myOutput2 = CallMethod2(param1, param2, our errorMsg)
       if (error)
       { // do something, then break }
    
       ...
    
       myOutput9 = CallMethod9(param1, param2, our errorMsg)
       if (error)
       { // do something, then break }
    

    示例构思管道代码 也许是这样的?会有用吗?我该如何改进呢?

    public class Reporter
    {
       private ReportSettings Settings {get; set;}
       private ReportResponse Response {get; set;}
    
       public ReportResponse GenerateAndSendReports(string groupName)
       {
           ReportResponse response = this.GetInputConfiguration()
                                     .ValidateConfiguration()
                                     .StandardizeConfiguration(groupName)
                                     .PopulateReport1()
                                     .PopulateReport2()
                                     .PopulateReport99()
                                     .EmailReports()
                                     .Output();
    
    
          return response;
        }
    
       public Reporter GetInputConfiguration()
       {
            this.Response = new ReportResponse();
            this.Settings = new ReportSetting();
    
            this.Settings.IsReport1Enabled = ConfigurationManager.GetSetting("EnableReport1");
            this.Settings.Blah1 = ConfigurationManager.GetSetting("Blah1");
            this.Settings.Blah2 = ConfigurationManager.GetSetting("Blah2");
             return this;
    }
    
       public Reporter StandardizeConfiguration(string groupName)
       {
            this.Settings.Emails = myDataService.GetEmails(groupName);
            return this;
       }
    
    public Reporter PopulateReport1()
    {
        if (!this.Setting.HasError && this.Settings.IsReport1Enabled)
        {
            try
            {
                this.Response.Report1Content = myReportService.GetReport1(this.Settings.Blah1, this.Blah2)
            }
            catch (Exception ex)
            {
                this.Response.HasError = true;
                this.Response.Message = ex.ToString();
            }
        }
        return this;
    }
    }
    

    我在想这样的事情

1 个答案:

答案 0 :(得分:0)

您提到了两个不同的概念:流利机制和管道(或责任链)模式。

流水线模式

  • 必须定义一个包含 IPipeline 的接口 DoThings();
  • IPipeline 的实现必须包含一个 IPipeline GetNext();

流利

  • 所有操作都必须返回对被操作修改的对象的引用:IFluent
  • 如果您想更好地控制哪些选项可用以及何时在您的工作流程中可用,您可以让 Fluent 操作返回不同的界面:例如 IValidatedData 可以公开 IStandardizedData Standardize()IStandardizedData可以暴露 IStandardizedData PopulateReport(var param)IStandardizedData PopulateEmail(var param)。这就是 LINQ 对枚举、列表等所做的。

但是,在您的示例中,您似乎主要是在寻找 Fluent 机制。管道模式有助于数据流(例如 HTTP 请求处理程序)。在您的情况下,您只是将属性应用于单个对象 Reporter,因此管道模式并不真正适用。

对于那些因为正在寻找双向(推和拉)流畅管道而到此结束的人,您希望通过返回 IPipelineStep 的流畅操作来构建管道。管道的行为由每个 IPipelineStep 的实现定义。

您可以通过以下方式实现:

  • PipelineStep 实现 IPipelineStep
  • PipelineStep 包含一个 private IPipelineStep NextStep(get;set);
  • IPipelineBuilder 包含可用于构建管道的流畅操作。
  • 您流畅的操作会返回一个实现 IPipelineStepIPipelineBuilder 的具体化。
  • 在返回之前,fluent 操作更新 this.NextStep
  • IPipelineStep 包含 var Push(var input);var Pull(var input);
  • Push 做事然后调用 this.NextStep.Push
  • Pull 调用 this.NextStep.Pull,然后执行操作并返回

您还需要考虑在管道构建后如何使用:从上到下或相反。