Skip to content

Instantly share code, notes, and snippets.

@kemsky
Created July 4, 2023 16:52
Show Gist options
  • Save kemsky/a4522194ad30aa6854a952435f193462 to your computer and use it in GitHub Desktop.
Save kemsky/a4522194ad30aa6854a952435f193462 to your computer and use it in GitHub Desktop.
[Medium] Use case
public static class Specifications
{
// create specification from expression, delegate is compiled on first usage
public static readonly Specification<Department> ActiveDepartment = new(x => x.Active);
// create specification from delegate, expression is decompiled from delegate on first usage
public static readonly Specification<User> ActiveUser = new(
default,
x => x.Active
);
// negation
public static readonly Specification<User> InactiveUser = !ActiveUser;
// combination
public static readonly Specification<User> SubscribedUser = ActiveUser && new Specification<User>(x => x.Subscription == Subscription.Subscribed);
// create from expression and delegate because in DB collation is case insensitive
public static readonly Specification<Department> CustomerServiceDepartment = new(
x => x.Name == "Customer Service",
x => string.Equals(x.Name?.TrimEnd(), "Customer Service", StringComparison.InvariantCultureIgnoreCase)
);
// reuse ActiveDepartment specification inside another specification
public static readonly Specification<User> UserInCustomerServiceDepartment = new(x => x.Departments.Any(CustomerServiceDepartment && ActiveDepartment));
}
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(Specifications.ActiveUser) // 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(Specifications.ActiveUser) // 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