Philiprehberger.Specification

Specification pattern implementation for composable, reusable query filters.
Installation
dotnet add package Philiprehberger.Specification
Usage
Define Specifications
using Philiprehberger.Specification;
using System.Linq.Expressions;
public class IsActive : Specification<User>
{
public override Expression<Func<User, bool>> ToExpression()
=> user => user.IsActive;
}
public class HasMinimumAge : Specification<User>
{
private readonly int _minimumAge;
public HasMinimumAge(int minimumAge) => _minimumAge = minimumAge;
public override Expression<Func<User, bool>> ToExpression()
=> user => user.Age >= _minimumAge;
}
Compose Specifications
var isActive = new IsActive();
var isAdult = new HasMinimumAge(18);
// Combine with And, Or, Not
var activeAdult = isActive.And(isAdult);
var inactiveOrMinor = isActive.Not().Or(isAdult.Not());
Check Entities
var spec = new IsActive().And(new HasMinimumAge(18));
bool satisfies = spec.IsSatisfiedBy(user);
Filter Queryables
var spec = new IsActive().And(new HasMinimumAge(18));
// Extension method
IQueryable<User> results = dbContext.Users.Where(spec);
// Or via evaluator
IQueryable<User> results = SpecificationEvaluator.Evaluate(dbContext.Users, spec);
Implicit Conversion
Expression<Func<User, bool>> expr = new IsActive();
var results = dbContext.Users.Where(expr);
API
Specification<T>
| Member | Description |
|---|
ToExpression() | Convert to a LINQ expression tree |
IsSatisfiedBy(T entity) | Check if an entity satisfies the specification |
implicit operator Expression<Func<T, bool>> | Implicit conversion to expression |
SpecificationExtensions
| Method | Description |
|---|
And<T>(Specification<T>, Specification<T>) | Combine with logical AND |
Or<T>(Specification<T>, Specification<T>) | Combine with logical OR |
Not<T>(Specification<T>) | Negate with logical NOT |
QueryableExtensions
| Method | Description |
|---|
Where<T>(IQueryable<T>, Specification<T>) | Filter a queryable using a specification |
SpecificationEvaluator
| Method | Description |
|---|
Evaluate<T>(IQueryable<T>, Specification<T>) | Apply a specification to a queryable source |
Development
dotnet build src/Philiprehberger.Specification.csproj --configuration Release
Support
If you find this project useful:
⭐ Star the repo
🐛 Report issues
💡 Suggest features
❤️ Sponsor development
🌐 All Open Source Projects
💻 GitHub Profile
🔗 LinkedIn Profile
License
MIT