Skip to content

Instantly share code, notes, and snippets.

@omerfarukz
Last active January 4, 2022 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omerfarukz/69592f5d73b6ac9fe31a89c502ecfa1d to your computer and use it in GitHub Desktop.
Save omerfarukz/69592f5d73b6ac9fe31a89c502ecfa1d to your computer and use it in GitHub Desktop.
var floatToStringPipe = new FuncPipe<float, string>(f => $"Given {f}")
.Then(new FuncPipe<string, int>(f => f.Length))
.Then(new FuncPipe<int, string>(f => String.Join(String.Empty, Enumerable.Range(1, f + 1))));
var result = floatToStringPipe.Execute(3.14f); // float, string
Console.WriteLine(result);
// 1234567891011
var toBoldAndItalic = new ToHtmlBoldPipe().Then(new ToHtmlUnderlinePipe());
var html = toBoldAndItalic.Execute("Hello"); // string, string
Console.WriteLine(html);
// <u><strong>Hello</strong></u>
var toBoldAndItalic2 = new ToHtmlBoldPipe().Then<ToHtmlUnderlinePipe>();
Console.WriteLine(toBoldAndItalic2.Execute("World")); // object, object
// <u><strong>World</strong></u>
internal class ToHtmlBoldPipe : ToHtmlWrappingContent
{
public ToHtmlBoldPipe() : base("strong")
{ }
}
internal class ToHtmlUnderlinePipe : ToHtmlWrappingContent
{
public ToHtmlUnderlinePipe() : base("u")
{ }
}
internal class ToHtmlWrappingContent : Pipe<string, string>
{
private readonly string tag;
public ToHtmlWrappingContent(string tag)
{
this.tag = tag;
}
public override string Execute(string input)
{
return $"<{tag}>{input}</{tag}>";
}
}
public static class PipelineExtensions
{
public static IPipe<TInput, TOutput> Then<TInput, TConnector, TOutput>(this IPipe<TInput, TConnector> current, IPipe<TConnector, TOutput> next)
{
return new FuncPipe<TInput, TOutput>(f =>
{
var currentPipeResult = current.Execute(f);
var nextPipeResult = next.Execute(currentPipeResult);
return nextPipeResult;
});
}
public static IPipe<TInput, TOutput> Then<TInput, TConnector, TOutput>(this IPipe<TInput, TConnector> current, Func<TConnector, TOutput> next)
{
var nextPipe = new FuncPipe<TConnector, TOutput>(next);
return Then(current, nextPipe);
}
public static IPipe<TInput, TOutput> Then<TInput, TConnector, TOutput>(this Func<TInput, TConnector> current, Func<TConnector, TOutput> next)
{
var currentPipe = new FuncPipe<TInput, TConnector>(current);
var nextPipe = new FuncPipe<TConnector, TOutput>(next);
return Then(currentPipe, nextPipe);
}
public static IPipe<TInput, TOutput> Then<TInput, TConnector, TOutput>(this Func<TInput, TConnector> current, IPipe<TConnector, TOutput> next)
{
var currentPipe = new FuncPipe<TInput, TConnector>(current);
return Then(currentPipe, next);
}
public static FuncPipe<object, object> Then<TPipe>(this IPipe current) where TPipe : IPipe
{
return new FuncPipe<object, object>(f => {
var currentValue = current.Execute(f);
var nextPipe = Activator.CreateInstance<TPipe>();
return nextPipe.Execute(currentValue);
});
}
}
public interface IPipe
{
object Execute(object input);
}
public interface IPipe<TInput, TOutput> : IPipe
{
new TOutput Execute(TInput input);
}
public abstract class Pipe<TInput, TOutput> : IPipe<TInput, TOutput>
{
public abstract TOutput Execute(TInput input);
public object Execute(object input)
{
return Execute((TInput)input);
}
}
public class FuncPipe<TInput, TOutput> : Pipe<TInput, TOutput>, IPipe<TInput, TOutput>
{
private readonly Func<TInput, TOutput> func;
public FuncPipe(Func<TInput, TOutput> func)
{
this.func = func ?? throw new ArgumentNullException(nameof(func));
}
public override TOutput Execute(TInput input)
{
return func(input);
}
public static implicit operator FuncPipe<TInput, TOutput>(Func<TInput, TOutput> func)
{
return new FuncPipe<TInput, TOutput>(func);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment