title: How to implement specification pattern?
body: <p>In my project; I have included specific pattern classes that are given below. I dont know how to implement this. These codes are included by previous developers.</p>
  
  <pre><code>public interface ISpecification&lt;T&gt;
  {
      Expression&lt;Func&lt;T, bool&gt;&gt; SpecExpression { get; }
      bool IsSatisfiedBy(T obj);
  }
  
  public static class IExtensions
  {
      public static ISpecification&lt;T&gt; And&lt;T&gt;(
          this ISpecification&lt;T&gt; left,
          ISpecification&lt;T&gt; right)
      {
          return new And&lt;T&gt;(left, right);
      }
  
      public static ISpecification&lt;T&gt; Or&lt;T&gt;(
          this ISpecification&lt;T&gt; left,
          ISpecification&lt;T&gt; right)
      {
          return new Or&lt;T&gt;(left, right);
      }
  
      public static ISpecification&lt;T&gt; Negate&lt;T&gt;(this ISpecification&lt;T&gt; inner)
      {
          return new Negated&lt;T&gt;(inner);
      }
  }
  
  public abstract class SpecificationBase&lt;T&gt; : ISpecification&lt;T&gt;
  {
      private Func&lt;T, bool&gt; _compiledExpression;
  
      private Func&lt;T, bool&gt; CompiledExpression
      {
          get { return _compiledExpression ?? (_compiledExpression = SpecExpression.Compile()); }
      }
  
      public abstract Expression&lt;Func&lt;T, bool&gt;&gt; SpecExpression { get; }
  
      public bool IsSatisfiedBy(T obj)
      {
          return CompiledExpression(obj);
      }
  }
  
  public class And&lt;T&gt; : SpecificationBase&lt;T&gt;
  {
      ISpecification&lt;T&gt; left;
      ISpecification&lt;T&gt; right;
  
      public And(
          ISpecification&lt;T&gt; left,
          ISpecification&lt;T&gt; right)
      {
          this.left = left;
          this.right = right;
      }
  
      // AndSpecification
      public override Expression&lt;Func&lt;T, bool&gt;&gt; SpecExpression
      {
          get
          {
              var objParam = Expression.Parameter(typeof(T), "obj");
  
              var newExpr = Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(
                  Expression.AndAlso(
                      Expression.Invoke(left.SpecExpression, objParam),
                      Expression.Invoke(right.SpecExpression, objParam)
                  ),
                  objParam
              );
  
              return newExpr;
          }
      }
  }
  
  public class Or&lt;T&gt; : SpecificationBase&lt;T&gt;
  {
      ISpecification&lt;T&gt; left;
      ISpecification&lt;T&gt; right;
  
      public Or(
          ISpecification&lt;T&gt; left,
          ISpecification&lt;T&gt; right)
      {
          this.left = left;
          this.right = right;
      }
  
      // OrSpecification
      public override Expression&lt;Func&lt;T, bool&gt;&gt; SpecExpression
      {
          get
          {
              var objParam = Expression.Parameter(typeof(T), "obj");
  
              var newExpr = Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(
                  Expression.OrElse(
                      Expression.Invoke(left.SpecExpression, objParam),
                      Expression.Invoke(right.SpecExpression, objParam)
                  ),
                  objParam
              );
  
              return newExpr;
          }
      }
  }
  
   public class Negated&lt;T&gt; : SpecificationBase&lt;T&gt;
  {
      private readonly ISpecification&lt;T&gt; _inner;
  
      public Negated(ISpecification&lt;T&gt; inner)
      {
          _inner = inner;
      }
  
      // NegatedSpecification
      public override Expression&lt;Func&lt;T, bool&gt;&gt; SpecExpression
      {
          get
          {
              var objParam = Expression.Parameter(typeof(T), "obj");
  
              var newExpr = Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(
                  Expression.Not(
                      Expression.Invoke(this._inner.SpecExpression, objParam)
                  ),
                  objParam
              );
  
              return newExpr;
          }
      }
  }
  </code></pre>
  
  <p>How to implement above specification with a simple example? What is the use of this specification?</p>