Skip to content

Instantly share code, notes, and snippets.

@marcingolenia
Created October 15, 2019 19:57
Show Gist options
  • Save marcingolenia/2d2409f3b9b09b28c0d4cd44aaf0c2a2 to your computer and use it in GitHub Desktop.
Save marcingolenia/2d2409f3b9b09b28c0d4cd44aaf0c2a2 to your computer and use it in GitHub Desktop.
public class OrSpecification<T> : Specification<T>
{
private readonly Specification<T> _left;
private readonly Specification<T> _right;
public OrSpecification(Specification<T> left, Specification<T> right)
{
_right = right;
_left = left;
}
public override Expression<Func<T, bool>> ToExpression()
{
var (leftExpression, rightExpression) = (_left.ToExpression(), _right.ToExpression());
var paramExpr = Expression.Parameter(typeof(T));
var exprBody = Expression.OrElse(leftExpression.Body, rightExpression.Body);
exprBody = (BinaryExpression)new ParameterReplacer(paramExpr).Visit(exprBody);
return Expression.Lambda<Func<T, bool>>(exprBody, paramExpr);
}
private class ParameterReplacer : ExpressionVisitor
{
private readonly ParameterExpression _parameter;
internal ParameterReplacer(ParameterExpression parameter) => _parameter = parameter;
protected override Expression VisitParameter(ParameterExpression node) => base.VisitParameter(_parameter);
}
}
public abstract class Specification<T>
{
public abstract Expression<Func<T, bool>> ToExpression();
public bool IsSatisfiedBy(T entity) => ToExpression().Compile()(entity);
public Specification<T> Or(Specification<T> specification) => new OrSpecification<T>(this, specification);
}
//sample impl
public class EqualZeroSpecification : Specification<int>
{
public override Expression<Func<int, bool>> ToExpression() => number => number == 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment