alexey-savchenko-am / Dataflow.Pipeline

A simple pipeline representation for .NET. Represents a sequence of steps which process consistently.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dataflow.Pipeline

A simple pipeline representation for .NET.
Represents a sequence of steps which process consistently.
It allows to break down a large bunch of code into small pieces for better readability, extensibility and testability.

NuGet version (Dataflow.Pipeline) Downloads

Usage

First of all you should create a type which will be passed between the pipeline steps:

public class InsurancePremiumModel
{
  public decimal TotalPremium { get; set; }
}

Use PipelineBuilder to create pipeline and fill one with steps. As an example lets assume that we want to calculate common insurance premium for set of customers:

var customers = GetCustomers();
var customersCount = customers.Count();

var builder = PipelineBuilder<InsurancePremiumModel>
  .StartWith((model, next) => {
    var basePrice = GetBasePrice(Options.Ambulance, customers);
    var ambulancePremium = _ambulanceService.Calculate(basePrice);
    model.TotalPremium += customersCount * ambulancePremium;
    return next.Invoke(model);
  })
  .AddStep((model, next) => {
    var basePrice = GetBasePrice(Options.Dental, customers);
    var dentalPremium = _dentalService.Calculate(basePrice);
    model.TotalPremium += customersCount * dentalPremium;
    return next.Invoke(model);
  })
  .AddStep((model, next) => {
    var basePrice = GetBasePrice(Options.HomeCare, customers);
    var homeCarePremium = _homeCareService.Calculate(basePrice);
    model.TotalPremium += customersCount * homeCarePremium;
    return next.Invoke(model);
  });

It is possible to describe a pipeline step as a type by implementing an interface IPipelineStep. In an example below we create RoundOffStep to round off total insurance premium we got:

public class RoundOffStep
  : IPipelineStep<PriceModel>
  {
        public Task<PriceModel> InvokeAsync(PriceModel input, Func<PriceModel, Task<PriceModel>> next)
        {
            input.TotalPremium = RoundOff(input.TotalPremium);
            return next.Invoke(input);
        }
        
        private decimal RoundOff(decimal price)
        {
            var rem = price % 10;
            
            if (rem == 0) return price;
            
            var result = Math.Round(price / 10, MidpointRounding.AwayFromZero) * 10;

            return rem < 5 ? result + 10.00m : result;
        }

    }

So, you can add newly created step to builder like this:

  builder.AddStep<RoundOffStep>();

To obtain pipeline object use method Build of PipelineBuilder. After that you can call method ExecuteAsync of pipeline to perform all added steps:

  var pipeline = builder.Build();
  var result = await pipeline.ExecuteAsync(new InsurancePremiumModel());

About

A simple pipeline representation for .NET. Represents a sequence of steps which process consistently.

License:MIT License


Languages

Language:C# 100.0%