using System; using System.Linq.Expressions; namespace MyCode.Project.Infrastructure { /// /// Represents the base class for specifications. /// /// The type of the object to which the specification is applied. public abstract class Specification : ISpecification { #region Public Methods /// /// Evaluates a LINQ expression to its corresponding specification. /// /// The LINQ expression to be evaluated. /// The specification which represents the same semantics as the given LINQ expression. public static Specification Eval(Expression> expression) { return new ExpressionSpecification(expression); } #endregion #region ISpecification Members /// /// Returns a value which indicates whether the specification /// is satisfied by the given object. /// /// The object to which the specification is applied. /// True if the specification is satisfied, otherwise false. public virtual bool IsSatisfiedBy(T obj) { return this.GetExpression().Compile()(obj); } /// /// Combines the current specification instance with another specification instance /// and returns the combined specification which represents that both the current and /// the given specification must be satisfied by the given object. /// /// The specification instance with which the current specification /// is combined. /// The combined specification instance. public ISpecification And(ISpecification other) { return new AndSpecification(this, other); } /// /// Combines the current specification instance with another specification instance /// and returns the combined specification which represents that either the current or /// the given specification should be satisfied by the given object. /// /// The specification instance with which the current specification /// is combined. /// The combined specification instance. public ISpecification Or(ISpecification other) { return new OrSpecification(this, other); } /// /// Combines the current specification instance with another specification instance /// and returns the combined specification which represents that the current specification /// should be satisfied by the given object but the specified specification should not. /// /// The specification instance with which the current specification /// is combined. /// The combined specification instance. public ISpecification AndNot(ISpecification other) { return new AndNotSpecification(this, other); } /// /// Reverses the current specification instance and returns a specification which represents /// the semantics opposite to the current specification. /// /// The reversed specification instance. public ISpecification Not() { return new NotSpecification(this); } /// /// Gets the LINQ expression which represents the current specification. /// /// The LINQ expression. public abstract Expression> GetExpression(); #endregion } }