Skip to content

Instantly share code, notes, and snippets.

@Shamar
Last active December 28, 2015 03:19
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 Shamar/7433830 to your computer and use it in GitHub Desktop.
Save Shamar/7433830 to your computer and use it in GitHub Desktop.
A generic fluent interface example (too easy to actually require a fluent interface, http://ocramius.github.io/blog/fluent-interfaces-are-evil/).
using System;
using NUnit.Framework;
namespace FluentSample
{
public interface IFluentCounter
{
IFluentCounter Increase();
IFluentCounter Decrease();
int Value { get; }
}
public interface IFluentCounter<T> : IFluentCounter
where T : IFluentCounter<T>
{
new T Increase();
new T Decrease();
}
public class NaturalCounter : IFluentCounter<NaturalCounter>
{
private readonly Int32 _value;
public NaturalCounter(Int32 value)
{
_value = value;
}
#region IFluentCounter<NaturalCounter> Members
public NaturalCounter Increase()
{
return new NaturalCounter(_value + 1);
}
public NaturalCounter Decrease()
{
if (_value > 0)
return new NaturalCounter(_value - 1);
return new NaturalCounter(0);
}
#endregion
#region IFluentCounter Members
public int Value
{
get { return _value; }
}
IFluentCounter IFluentCounter.Increase()
{
return Increase();
}
IFluentCounter IFluentCounter.Decrease()
{
return Decrease();
}
#endregion
}
public class EchoingCounter<T> : IFluentCounter<EchoingCounter<T>>
where T : IFluentCounter<T>
{
private readonly T _inner;
public EchoingCounter(T inner)
{
_inner = inner;
}
#region IFluentCounter<EchoingCounter<T>> Members
public EchoingCounter<T> Increase()
{
Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
return new EchoingCounter<T>(_inner.Increase());
}
public EchoingCounter<T> Decrease()
{
Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
return new EchoingCounter<T>(_inner.Decrease());
}
#endregion
#region IFluentCounter Members
public int Value
{
get { return _inner.Value; }
}
IFluentCounter IFluentCounter.Increase()
{
return Increase();
}
IFluentCounter IFluentCounter.Decrease()
{
return Decrease();
}
#endregion
}
public abstract class FluentCounterImplementationsTesterBase<T>
where T : IFluentCounter<T>
{
protected abstract T StartWith(Int32 value);
[Test]
public void Increase_twiceFromZero_produceANewInstanceWithValue2()
{
// arrange:
T toTest = StartWith(0);
// act:
T result = toTest.Increase().Increase();
// assert:
Assert.AreNotSame(toTest, result);
Assert.AreEqual(2, result.Value);
}
[Test]
public void Decrease_twiceFromFour_produceANewInstanceWithValue2()
{
// arrange:
T toTest = StartWith(4);
// act:
T result = toTest.Decrease().Decrease();
// assert:
Assert.AreNotSame(toTest, result);
Assert.AreEqual(2, result.Value);
}
}
[TestFixture]
public class NaturalCounterTester : FluentCounterImplementationsTesterBase<NaturalCounter>
{
protected override NaturalCounter StartWith(Int32 value)
{
return new NaturalCounter(value);
}
}
[TestFixture]
public class EchoingCounterTester : FluentCounterImplementationsTesterBase<EchoingCounter<NaturalCounter>>
{
protected override EchoingCounter<NaturalCounter> StartWith(Int32 value)
{
return new EchoingCounter<NaturalCounter>(new NaturalCounter(value));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment