using System;
namespace Spec_Spike
{ class Program
{ static void Main()
{
Foo foo1 = new Foo();
foo1.Bar = "Test";
ISpecification<Foo> equalSpec = new Specification<Foo>(foo => foo.Bar == "Test");
ISpecification<Foo> notEqualSpec = new Specification<Foo>(foo => foo.Bar != "Not Equal To This Text");
ISpecification<Foo> falseSpec = new Specification<Foo>(foo => false);
ISpecification<Foo> passingSpec = equalSpec.And(notEqualSpec);
ISpecification<Foo> failingSpec = passingSpec.And(falseSpec);
Console.WriteLine(equalSpec.IsSatisfiedBy(foo1));
Console.WriteLine(notEqualSpec.IsSatisfiedBy(foo1));
Console.WriteLine(passingSpec.IsSatisfiedBy(foo1));
Console.WriteLine(failingSpec.IsSatisfiedBy(foo1));
}
}
public class Foo
{ public string Bar;
}
public interface ISpecification<t>
{ bool IsSatisfiedBy(t obj);
ISpecification<t> And(ISpecification<t> lhs);
}
public class Specification<t>: ISpecification<t>
{ private readonly Predicate<t> _pred;
public Specification(Predicate<t> pred)
{ _pred = pred;
}
protected Specification(){}
public virtual bool IsSatisfiedBy(t obj)
{ return _pred(obj);
}
public ISpecification<t> And(ISpecification<t> andSpec)
{ return new AndSpecification<t>(this, andSpec);
}
}
public class AndSpecification<t>: Specification<t>
{ private readonly ISpecification<t> _spec1;
private readonly ISpecification<t> _spec;
public AndSpecification(ISpecification<t> spec1, ISpecification<t> spec)
{ _spec1 = spec1;
_spec = spec;
}
public override bool IsSatisfiedBy(t obj)
{ return (_spec.IsSatisfiedBy(obj) && _spec1.IsSatisfiedBy(obj));
}
}
}