Skip to content

Instantly share code, notes, and snippets.

@panesofglass
Created October 26, 2009 16:15
Show Gist options
  • Save panesofglass/218765 to your computer and use it in GitHub Desktop.
Save panesofglass/218765 to your computer and use it in GitHub Desktop.
Extension methods for creating composite Specifications.
using System;
using System.Linq.Expressions;
namespace Foundation.Specifications
{
/// <summary>
/// A composite specification.
/// </summary>
/// <seealso href="http://www.lostechies.com/blogs/chrismissal/archive/2009/09/10/using-the-specification-pattern-for-querying.aspx" />
public static class CompositeSpecification
{
#region methods
/// <summary>
/// Returns the specification's condition as an Expression.
/// </summary>
/// <typeparam name="T">The type of the specification.</typeparam>
/// <param name="specification">The specification.</param>
/// <returns></returns>
public static Expression<Func<T, bool>> AsCondition<T>(this ISpecification<T> specification)
{
if (!(specification is Specification<T>))
{
throw new ArgumentException(
"In order to convert a specification into an Expression, the specification must inherit from the Specification<T> class.",
"specification");
}
return ((Specification<T>)specification).Condition;
}
/// <summary>
/// Applies a logical AND between the current and second specifications.
/// </summary>
/// <typeparam name="T">The type of the specification.</typeparam>
/// <param name="left">The left specification.</param>
/// <param name="right">The right specification.</param>
/// <returns>The composite specification.</returns>
public static ISpecification<T> And<T>(this ISpecification<T> left, ISpecification<T> right)
{
return new AndSpecification<T>(left, right);
}
/// <summary>
/// Applies a logical NOT to the current specification.
/// </summary>
/// <typeparam name="T">The type of the specification.</typeparam>
/// <param name="specification">The specification.</param>
/// <returns>The composite specification.</returns>
public static ISpecification<T> Not<T>(this ISpecification<T> specification)
{
return new NotSpecification<T>(specification);
}
/// <summary>
/// Applies a logical OR between the current and other specifications.
/// </summary>
/// <typeparam name="T">The type of the specification.</typeparam>
/// <param name="left">The left specification.</param>
/// <param name="right">The right specification.</param>
/// <returns>The composite specification.</returns>
public static ISpecification<T> Or<T>(this ISpecification<T> left, ISpecification<T> right)
{
return new OrSpecification<T>(left, right);
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment