Skip to content

Instantly share code, notes, and snippets.

@ralfw
Created September 3, 2013 10:38
Show Gist options
  • Save ralfw/6422281 to your computer and use it in GitHub Desktop.
Save ralfw/6422281 to your computer and use it in GitHub Desktop.
Pipes and filters à la Steve Bate - but with another twist. This time the message flowing through the pipe can change its type.
public class Pipeline
{
public interface IFilter<in TIN,out TOUT>
{
TOUT Process(TIN message);
}
private readonly IList<Func<object,object>> _stages = new List<Func<object,object>>();
public Pipeline Register<TIN,TOUT>(IFilter<TIN,TOUT> singletonFilter)
{
_stages.Add(msg => singletonFilter.Process((TIN)msg));
return this;
}
public Pipeline Register<F, TIN,TOUT>() where F : IFilter<TIN,TOUT>, new()
{
_stages.Add(msg =>
{
var f = new F();
return f.Process((TIN)msg);
});
return this;
}
public Pipeline Register<TIN,TOUT>(Func<TIN,TOUT> filter)
{
_stages.Add(msg => filter((TIN)msg));
return this;
}
public TRESULT Process<TRESULT>(object message)
{
return (TRESULT)_stages.Aggregate(message, (current, stage) => stage(current));
}
}
class Program
{
static void Main()
{
var sf = new SingletonFilter2();
var p = new Pipeline();
p.Register(sf)
.Register<PerMessageFilter2, string, StringBuilder>()
.Register<StringBuilder, string>(sb => sb.Append("L;").ToString());
var result = p.Process<string>(42);
Console.WriteLine(result);
}
}
class SingletonFilter2 : Pipeline.IFilter<int,string>
{
public string Process(int message)
{
return "SF2:" + message + ";";
}
}
class PerMessageFilter2 : Pipeline.IFilter<string,StringBuilder>
{
public StringBuilder Process(string message)
{
return new StringBuilder(message + "PMF;");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment