1231
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the combined specification which indicates that the first specification
|
||||
/// can be satisifed by the given object whereas the second one cannot.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public class AndNotSpecification<T> : CompositeSpecification<T>
|
||||
{
|
||||
#region Ctor
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <c>AndNotSpecification<T></c> class.
|
||||
/// </summary>
|
||||
/// <param name="left">The first specification.</param>
|
||||
/// <param name="right">The second specification.</param>
|
||||
public AndNotSpecification(ISpecification<T> left, ISpecification<T> right) : base(left, right) { }
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
public override Expression<Func<T, bool>> GetExpression()
|
||||
{
|
||||
var bodyNot = Expression.Not(Right.GetExpression().Body);
|
||||
var bodyNotExpression = Expression.Lambda<Func<T, bool>>(bodyNot, Right.GetExpression().Parameters);
|
||||
|
||||
return Left.GetExpression().And(bodyNotExpression);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the combined specification which indicates that both of the given
|
||||
/// specifications should be satisfied by the given object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public class AndSpecification<T> : CompositeSpecification<T>
|
||||
{
|
||||
#region Ctor
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <c>AndSpecification<T></c> class.
|
||||
/// </summary>
|
||||
/// <param name="left">The first specification.</param>
|
||||
/// <param name="right">The second specification.</param>
|
||||
public AndSpecification(ISpecification<T> left, ISpecification<T> right) : base(left, right) { }
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
public override Expression<Func<T, bool>> GetExpression()
|
||||
{
|
||||
//var body = Expression.AndAlso(Left.GetExpression().Body, Right.GetExpression().Body);
|
||||
//return Expression.Lambda<Func<T, bool>>(body, Left.GetExpression().Parameters);
|
||||
return Left.GetExpression().And(Right.GetExpression());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the specification that can be satisfied by the given object
|
||||
/// in any circumstance.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public sealed class AnySpecification<T> : Specification<T>
|
||||
{
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
public override Expression<Func<T, bool>> GetExpression()
|
||||
{
|
||||
return o => true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the base class for composite specifications.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public abstract class CompositeSpecification<T> : Specification<T>, ICompositeSpecification<T>
|
||||
{
|
||||
#region Private Fields
|
||||
private readonly ISpecification<T> left;
|
||||
private readonly ISpecification<T> right;
|
||||
#endregion
|
||||
|
||||
#region Ctor
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <c>CompositeSpecification<T></c> class.
|
||||
/// </summary>
|
||||
/// <param name="left">The first specification.</param>
|
||||
/// <param name="right">The second specification.</param>
|
||||
public CompositeSpecification(ISpecification<T> left, ISpecification<T> right)
|
||||
{
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ICompositeSpecification Members
|
||||
/// <summary>
|
||||
/// Gets the first specification.
|
||||
/// </summary>
|
||||
public ISpecification<T> Left
|
||||
{
|
||||
get { return this.left; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the second specification.
|
||||
/// </summary>
|
||||
public ISpecification<T> Right
|
||||
{
|
||||
get { return this.right; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the extender for Expression[Func[T, bool]] type.
|
||||
/// This is part of the solution which solves
|
||||
/// the expression parameter problem when going to Entity Framework by using
|
||||
/// Apworks specifications. For more information about this solution please
|
||||
/// </summary>
|
||||
public static class ExpressionFuncExtender
|
||||
{
|
||||
#region Private Methods
|
||||
private static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
|
||||
{
|
||||
// build parameter map (from parameters of second to parameters of first)
|
||||
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
|
||||
|
||||
// replace parameters in the second lambda expression with parameters from the first
|
||||
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
|
||||
|
||||
// apply composition of lambda expression bodies to parameters from the first expression
|
||||
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Combines two given expressions by using the AND semantics.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object.</typeparam>
|
||||
/// <param name="first">The first part of the expression.</param>
|
||||
/// <param name="second">The second part of the expression.</param>
|
||||
/// <returns>The combined expression.</returns>
|
||||
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
|
||||
{
|
||||
return first.Compose(second, Expression.And);
|
||||
}
|
||||
/// <summary>
|
||||
/// Combines two given expressions by using the OR semantics.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object.</typeparam>
|
||||
/// <param name="first">The first part of the expression.</param>
|
||||
/// <param name="second">The second part of the expression.</param>
|
||||
/// <returns>The combined expression.</returns>
|
||||
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
|
||||
{
|
||||
return first.Compose(second, Expression.Or);
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建一个Lambda表达式
|
||||
/// </summary>
|
||||
/// <typeparam name="T">实体类型</typeparam>
|
||||
/// <param name="prop">实体属性</param>
|
||||
/// <param name="value">属性值</param>
|
||||
/// <param name="valueType">属性值的数据类型</param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T, bool>> CreateLambda<T>(string prop, object value, Type valueType = null)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "t");
|
||||
Expression property = null;
|
||||
string[] props = prop.Split('.');
|
||||
for (int i = 0; i < props.Length; i++)
|
||||
{
|
||||
if (property == null)
|
||||
{
|
||||
property = Expression.Property(parameter, props[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
property = Expression.Property(property, props[i]);
|
||||
}
|
||||
}
|
||||
var body = Expression.Equal(property, valueType != null ? Expression.Constant(value, valueType) : Expression.Constant(value));
|
||||
var lambda = Expression.Lambda<Func<T, bool>>(body, parameter);
|
||||
return lambda;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个Lambda表达式
|
||||
/// </summary>
|
||||
/// <typeparam name="T">实体类型</typeparam>
|
||||
/// <param name="prop">实体属性</param>
|
||||
/// <param name="value">属性值</param>
|
||||
/// <param name="valueType">属性值的数据类型</param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<object, bool>> CreateLambda(Type t, string prop, object value, Type valueType = null)
|
||||
{
|
||||
var parameter = Expression.Parameter(t, "t");
|
||||
Expression property = null;
|
||||
string[] props = prop.Split('.');
|
||||
for (int i = 0; i < props.Length; i++)
|
||||
{
|
||||
if (property == null)
|
||||
{
|
||||
property = Expression.Property(parameter, props[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
property = Expression.Property(property, props[i]);
|
||||
}
|
||||
}
|
||||
var body = Expression.Equal(property, valueType != null ? Expression.Constant(value, valueType) : Expression.Constant(value));
|
||||
var lambda = Expression.Lambda<Func<object, bool>>(body, Expression.Parameter(typeof(object), "t"));
|
||||
return lambda;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the specification which is represented by the corresponding
|
||||
/// LINQ expression.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
internal sealed class ExpressionSpecification<T> : Specification<T>
|
||||
{
|
||||
#region Private Fields
|
||||
private Expression<Func<T, bool>> expression;
|
||||
#endregion
|
||||
|
||||
#region Ctor
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>ExpressionSpecification<T></c> class.
|
||||
/// </summary>
|
||||
/// <param name="expression">The LINQ expression which represents the current
|
||||
/// specification.</param>
|
||||
public ExpressionSpecification(Expression<Func<T, bool>> expression)
|
||||
{
|
||||
this.expression = expression;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
public override Expression<Func<T, bool>> GetExpression()
|
||||
{
|
||||
return this.expression;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents that the implemented classes are composite specifications.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public interface ICompositeSpecification<T> : ISpecification<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the left side of the specification.
|
||||
/// </summary>
|
||||
ISpecification<T> Left { get; }
|
||||
/// <summary>
|
||||
/// Gets the right side of the specification.
|
||||
/// </summary>
|
||||
ISpecification<T> Right { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents that the implemented classes are specifications. For more
|
||||
/// information about the specification pattern, please refer to
|
||||
/// http://martinfowler.com/apsupp/spec.pdf.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification
|
||||
/// is applied.</typeparam>
|
||||
public interface ISpecification<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.Boolean"/> value which indicates whether the specification
|
||||
/// is satisfied by the given object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to which the specification is applied.</param>
|
||||
/// <returns>True if the specification is satisfied, otherwise false.</returns>
|
||||
bool IsSatisfiedBy(T obj);
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="other">The specification instance with which the current specification
|
||||
/// is combined.</param>
|
||||
/// <returns>The combined specification instance.</returns>
|
||||
ISpecification<T> And(ISpecification<T> other);
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="other">The specification instance with which the current specification
|
||||
/// is combined.</param>
|
||||
/// <returns>The combined specification instance.</returns>
|
||||
ISpecification<T> Or(ISpecification<T> other);
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="other">The specification instance with which the current specification
|
||||
/// is combined.</param>
|
||||
/// <returns>The combined specification instance.</returns>
|
||||
ISpecification<T> AndNot(ISpecification<T> other);
|
||||
/// <summary>
|
||||
/// Reverses the current specification instance and returns a specification which represents
|
||||
/// the semantics opposite to the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The reversed specification instance.</returns>
|
||||
ISpecification<T> Not();
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
Expression<Func<T, bool>> GetExpression();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents that the implemented classes are specification parsers that
|
||||
/// parses the given specification to a domain specific criteria object, such
|
||||
/// as the <c>ICriteria</c> instance in NHibernate.
|
||||
/// </summary>
|
||||
/// <typeparam name="TCriteria">The type of the domain specific criteria.</typeparam>
|
||||
public interface ISpecificationParser<TCriteria>
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses the given specification to a domain specific criteria object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
/// <param name="specification">The specified specification instance.</param>
|
||||
/// <returns>The instance of the domain specific criteria.</returns>
|
||||
TCriteria Parse<T>(ISpecification<T> specification);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the specification that can be satisfied by the given object
|
||||
/// in no circumstance.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public sealed class NoneSpecification<T> : Specification<T>
|
||||
{
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
public override Expression<Func<T, bool>> GetExpression()
|
||||
{
|
||||
return o => false;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the specification which indicates the semantics opposite to the given specification.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public class NotSpecification<T> : Specification<T>
|
||||
{
|
||||
#region Private Fields
|
||||
private ISpecification<T> spec;
|
||||
#endregion
|
||||
|
||||
#region Ctor
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>NotSpecification<T></c> class.
|
||||
/// </summary>
|
||||
/// <param name="specification">The specification to be reversed.</param>
|
||||
public NotSpecification(ISpecification<T> specification)
|
||||
{
|
||||
this.spec = specification;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
public override Expression<Func<T, bool>> GetExpression()
|
||||
{
|
||||
var body = Expression.Not(this.spec.GetExpression().Body);
|
||||
return Expression.Lambda<Func<T, bool>>(body, this.spec.GetExpression().Parameters);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the combined specification which indicates that either of the given
|
||||
/// specification should be satisfied by the given object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public class OrSpecification<T> : CompositeSpecification<T>
|
||||
{
|
||||
#region Ctor
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>OrSpecification<T></c> class.
|
||||
/// </summary>
|
||||
/// <param name="left">The first specification.</param>
|
||||
/// <param name="right">The second specification.</param>
|
||||
public OrSpecification(ISpecification<T> left, ISpecification<T> right) : base(left, right) { }
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
public override Expression<Func<T, bool>> GetExpression()
|
||||
{
|
||||
//var body = Expression.OrElse(Left.GetExpression().Body, Right.GetExpression().Body);
|
||||
//return Expression.Lambda<Func<T, bool>>(body, Left.GetExpression().Parameters);
|
||||
return Left.GetExpression().Or(Right.GetExpression());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the parameter rebinder used for rebinding the parameters
|
||||
/// for the given expressions. This is part of the solution which solves
|
||||
/// the expression parameter problem when going to Entity Framework by using
|
||||
/// Apworks specifications. For more information about this solution please
|
||||
/// refer to http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx.
|
||||
/// </summary>
|
||||
internal class ParameterRebinder : ExpressionVisitor
|
||||
{
|
||||
#region Private Fields
|
||||
private readonly Dictionary<ParameterExpression, ParameterExpression> map;
|
||||
#endregion
|
||||
|
||||
#region Ctor
|
||||
internal ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
|
||||
{
|
||||
this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Internal Static Methods
|
||||
internal static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
|
||||
{
|
||||
return new ParameterRebinder(map).Visit(exp);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
protected override Expression VisitParameter(ParameterExpression p)
|
||||
{
|
||||
ParameterExpression replacement;
|
||||
if (map.TryGetValue(p, out replacement))
|
||||
{
|
||||
p = replacement;
|
||||
}
|
||||
return base.VisitParameter(p);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace MyCode.Project.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the base class for specifications.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to which the specification is applied.</typeparam>
|
||||
public abstract class Specification<T> : ISpecification<T>
|
||||
{
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Evaluates a LINQ expression to its corresponding specification.
|
||||
/// </summary>
|
||||
/// <param name="expression">The LINQ expression to be evaluated.</param>
|
||||
/// <returns>The specification which represents the same semantics as the given LINQ expression.</returns>
|
||||
public static Specification<T> Eval(Expression<Func<T, bool>> expression)
|
||||
{
|
||||
return new ExpressionSpecification<T>(expression);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ISpecification<T> Members
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.Boolean"/> value which indicates whether the specification
|
||||
/// is satisfied by the given object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to which the specification is applied.</param>
|
||||
/// <returns>True if the specification is satisfied, otherwise false.</returns>
|
||||
public virtual bool IsSatisfiedBy(T obj)
|
||||
{
|
||||
return this.GetExpression().Compile()(obj);
|
||||
}
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="other">The specification instance with which the current specification
|
||||
/// is combined.</param>
|
||||
/// <returns>The combined specification instance.</returns>
|
||||
public ISpecification<T> And(ISpecification<T> other)
|
||||
{
|
||||
return new AndSpecification<T>(this, other);
|
||||
}
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="other">The specification instance with which the current specification
|
||||
/// is combined.</param>
|
||||
/// <returns>The combined specification instance.</returns>
|
||||
public ISpecification<T> Or(ISpecification<T> other)
|
||||
{
|
||||
return new OrSpecification<T>(this, other);
|
||||
}
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="other">The specification instance with which the current specification
|
||||
/// is combined.</param>
|
||||
/// <returns>The combined specification instance.</returns>
|
||||
public ISpecification<T> AndNot(ISpecification<T> other)
|
||||
{
|
||||
return new AndNotSpecification<T>(this, other);
|
||||
}
|
||||
/// <summary>
|
||||
/// Reverses the current specification instance and returns a specification which represents
|
||||
/// the semantics opposite to the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The reversed specification instance.</returns>
|
||||
public ISpecification<T> Not()
|
||||
{
|
||||
return new NotSpecification<T>(this);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the LINQ expression which represents the current specification.
|
||||
/// </summary>
|
||||
/// <returns>The LINQ expression.</returns>
|
||||
public abstract Expression<Func<T, bool>> GetExpression();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user