Last active
July 4, 2023 17:10
-
-
Save kemsky/fc60b9b6325eb349b0a9d1bb254a2b81 to your computer and use it in GitHub Desktop.
[Medium] Canonical specification implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// source: https://en.wikipedia.org/wiki/Specification_pattern | |
// see full implementation there | |
public interface ISpecification<T> | |
{ | |
bool IsSatisfiedBy(T candidate); | |
ISpecification<T> And(ISpecification<T> other); | |
ISpecification<T> AndNot(ISpecification<T> other); | |
ISpecification<T> Or(ISpecification<T> other); | |
ISpecification<T> OrNot(ISpecification<T> other); | |
ISpecification<T> Not(); | |
} | |
public abstract class LinqSpecification<T> : CompositeSpecification<T> | |
{ | |
public abstract Expression<Func<T, bool>> AsExpression(); | |
public override bool IsSatisfiedBy(T candidate) => AsExpression().Compile()(candidate); | |
} | |
public sealed class ActiveUserSpecification : LinqSpecification<User> | |
{ | |
public override Expression<Func<User, bool>> AsExpression() => x => x.Active; | |
} | |
public class UserService | |
{ | |
private readonly DbContext _context; | |
public UserService(DbContext context) | |
{ | |
_context = context; | |
} | |
public Task<User> GetUser(int userId) | |
{ | |
return _context.Set<User>() | |
.Where(x => x.userId == userId) | |
.Where(new ActiveUserSpecification().AsExpression()) // cool, we are using the same specification | |
.SingleOrDefaultAsync(); | |
} | |
public Task<User> GetUserInDepartment(int userId, int departmentId) | |
{ | |
return _context.Set<User>() | |
.Where(x => x.userId == userId) | |
.Where(new ActiveUserSpecification().AsExpression()) // cool, we are using the same specification | |
.Where(x => x.Departments.Any(z => z.Id == departmentId)) | |
.SingleOrDefaultAsync(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment