Skip to content

Instantly share code, notes, and snippets.

@ChrisMissal
Created October 18, 2010 18:36
Show Gist options
  • Save ChrisMissal/632759 to your computer and use it in GitHub Desktop.
Save ChrisMissal/632759 to your computer and use it in GitHub Desktop.
A generic set of .Net classes to handle a specification pattern.
public interface ISpecification<T>
{
bool IsSatisfiedBy(T candidate);
ISpecification<T> And(ISpecification<T> other);
ISpecification<T> Or(ISpecification<T> other);
ISpecification<T> Not();
}
public abstract class Specification<T> : ISpecification<T>
{
public abstract bool IsSatisfiedBy(T candidate);
public ISpecification<T> And(ISpecification<T> specification)
{
return new AndSpecification(this, specification);
}
public ISpecification<T> Or(ISpecification<T> specification)
{
return new OrSpecification(this, specification);
}
public ISpecification<T> Not()
{
return new NotSpecification(this);
}
internal abstract class CompositeSpecification : Specification<T>
{
protected readonly ISpecification<T> left;
protected readonly ISpecification<T> right;
protected CompositeSpecification(ISpecification<T> left, ISpecification<T> right)
{
this.left = left;
this.right = right;
}
}
internal class AndSpecification : CompositeSpecification
{
internal AndSpecification(ISpecification<T> left, ISpecification<T> right) : base(left, right)
{
}
public override bool IsSatisfiedBy(T candidate)
{
return left.IsSatisfiedBy(candidate) && right.IsSatisfiedBy(candidate);
}
}
internal class OrSpecification : CompositeSpecification
{
internal OrSpecification(ISpecification<T> left, ISpecification<T> right) : base(left, right)
{
}
public override bool IsSatisfiedBy(T candidate)
{
return left.IsSatisfiedBy(candidate) || right.IsSatisfiedBy(candidate);
}
}
internal class NotSpecification : Specification<T>
{
private readonly Specification<T> specification;
internal NotSpecification(Specification<T> specification)
{
this.specification = specification;
}
public override bool IsSatisfiedBy(T candidate)
{
return !specification.IsSatisfiedBy(candidate);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment