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
}
}