using System.Collections.Generic;
public int Id { get; protected set; }
public int Value { get; set; }
public Item(int id, int val)
protected readonly string _name;
public IEnumerable<Item> Input { get; protected set; }
public IEnumerable<Item> Output { get { return Apply(); } }
public Rule (IEnumerable<Item> input, string name)
protected virtual IEnumerable<Item> Apply()
foreach (var item in Input)
Console.WriteLine("Applying {0} {1} to Item.Id {2}", nameof(Rule), _name, item.Id);
public class StatefulRule : Rule
public StatefulRule(IEnumerable<Item> input, string name) : base(input, name) { }
protected override IEnumerable<Item> Apply()
var fullSetOfModifiedData = new List<Item>();
foreach (var item in Input)
Console.WriteLine("Applying {0} {1} to Item.Id {2}", nameof(StatefulRule), _name, item.Id);
public class BlockingRule : Rule
public BlockingRule(IEnumerable<Item> input, string name) : base(input, name) { }
protected override IEnumerable<Item> Apply()
var fullSetOfModifiedData = new Stack<Item>();
foreach (var item in Input)
fullSetOfModifiedData.Push(item);
Console.WriteLine("Applying {0} {1} to Item.Id {2}", nameof(BlockingRule), _name, item.Id);
Console.WriteLine("Finished applying {0} {1}, unblock next rule", nameof(BlockingRule), _name);
return fullSetOfModifiedData;
public static void Main()
var input = Enumerable.Range(1, 5)
.Select(x => new Item(x, x));
var ruleA = new Rule(input, "A");
var ruleB = new Rule(ruleA.Output, "B");
var ruleC = new StatefulRule(ruleB.Output, "C");
var ruleD = new BlockingRule(ruleC.Output, "D");
var ruleE = new Rule(ruleD.Output, "E");
var ruleF = new Rule(ruleE.Output, "F");
var processedItems = ruleF.Output;
foreach (var item in processedItems)
Console.WriteLine("out: " + item.Value);