Skip to content

Instantly share code, notes, and snippets.

@jmarnold
Created May 27, 2011 15:40
Show Gist options
  • Save jmarnold/995508 to your computer and use it in GitHub Desktop.
Save jmarnold/995508 to your computer and use it in GitHub Desktop.
Specifications, Policies, and Composition
public virtual IQueryable<T> Query(ISpecification<T> query)
{
var specifications = new List<ISpecification<T>>();
_specificationPolicies
.Where(p => p.Applies<T>())
.Select(p => p.Build<T>())
.Each(specifications.Add);
_entityPolicies
.Where(p => p.Applies())
.Select(p => p.Build())
.Each(specifications.Add);
specifications.Add(query);
var specification = _specificationComposer.Compose(specifications);
return Entities.Where(specification.IsSatisfied());
}
public static IQueryable<TEntity> Query<TEntity>(this IEntityRepository<TEntity> repository, Expression<Func<TEntity, bool>> predicate)
{
return repository.Query(predicate.ToSpecification());
}
public User FindByUserId(int userId)
{
return this.Query(u => u.UserId == userId).SingleOrDefault();
}
public User FindByUserId(int userId)
{
return DataContext.Users.SingleOrDefault(u => u.UserId == userId);
}
public interface IRepository
{
IQueryable<TEntity> Query<TEntity>(ISpecification<TEntity> query);
}
public interface ISpecification<T>
{
Expression<Func<T, bool>> IsSatisfied();
}
public interface ISystemSpecificationPolicy
{
bool Applies<TEntity>();
ISpecification<TEntity> Build<TEntity>();
}
public interface ISystemSpecificationPolicy<TEntity>
{
bool Applies();
ISpecification<TEntity> Build();
}
public static class QueryExtensions
{
public static ISpecification<TEntity> ToSpecification<TEntity>(this Expression<Func<TEntity, bool>> predicate)
{
return new LambdaSpecification<TEntity>(predicate);
}
public static IQueryable<TEntity> Query<TEntity>(this IRepository repository, Expression<Func<TEntity, bool>> predicate)
{
return repository.Query(predicate.ToSpecification());
}
}
public class SiteContextualEntityPolicy : ISystemSpecificationPolicy
{
private readonly SiteSettings _siteSettings;
public SiteContextualEntityPolicy(SiteSettings siteSettings)
{
_siteSettings = siteSettings;
}
public bool Applies<TEntity>()
{
return typeof (ISiteContextualEntity).IsAssignableFrom(typeof (TEntity));
}
public ISpecification<TEntity> Build<TEntity>()
{
return Specification
.For<ISiteContextualEntity>()
.Constrain<TEntity>(e => e.SiteId, _siteSettings.PrincipalSiteId);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment