定义规约:创建一个由 Specification 派生的新规约类
IsSatisfiedBy 方法可以用于检查单个对象是否满足规约
ToExpression 将规约转换为表达式,规约可以与And、Or、Not以及AndNot扩展方法组合使用
public class Customer : AggregateRoot<Guid>
{
public string Name { get; set; }
public byte Age { get; set; }
public long Balance { get; set; }
public string Location { get; set; }
}
//可以直接实现ISpecification<T>接口,但是基类Specification<T>做了大量简化.
public class Age18PlusCustomerSpecification : Specification<Customer>
{
public override Expression<Func<Customer, bool>> ToExpression()
{
//只需通过定义一个lambda表达式来定义规约
return c => c.Age >= 18;
return (customer) => (customer.Balance >= 100000);
}
}
public class CustomerService : ITransientDependency
{
public async Task BuyAlcohol(Customer customer)
{
//IsSatisfiedBy 方法可以用于检查单个对象是否满足规约
if (!new Age18PlusCustomerSpecification().IsSatisfiedBy(customer))
{
//如果顾客不满足年龄规定,则抛出异常
throw new Exception(
"这位顾客不满足年龄规定!"
);
}
//TODO...
}
}
public class CustomerManager : DomainService, ITransientDependency
{
private readonly IRepository<Customer, Guid> _customerRepository;
public CustomerManager(IRepository<Customer, Guid> customerRepository)
{
_customerRepository = customerRepository;
}
public async Task<List<Customer>> GetCustomersCanBuyAlcohol()
{
var queryable = await _customerRepository.GetQueryableAsync();
var query = queryable.Where(
//ToExpression() 方法可用于将规约转化为表达式.
//通过这种方式,你可以使用规约在数据库查询时过滤实体.
new Age18PlusCustomerSpecification().ToExpression()
);
//实际上,没有必要使用 ToExpression() 方法,因为规约会自动转换为表达式
var query = queryable.Where(
new Age18PlusCustomerSpecification()
);
return await AsyncExecuter.ToListAsync(query);
}
}
public class CustomerManager : DomainService, ITransientDependency
{
private readonly IRepository<Customer, Guid> _customerRepository;
public CustomerManager(IRepository<Customer, Guid> customerRepository)
{
_customerRepository = customerRepository;
}
public async Task<int> GetAdultPremiumCustomerCountAsync()
{
return await _customerRepository.CountAsync(
//规约可以与And、Or、Not以及AndNot扩展方法组合使用
new Age18PlusCustomerSpecification()
.And(new PremiumCustomerSpecification()).ToExpression()
);
}
}
创建一个可以复用的规约,派生自AndSpecification
public class AdultPremiumCustomerSpecification : AndSpecification<Customer>
{
public AdultPremiumCustomerSpecification()
: base(new Age18PlusCustomerSpecification(),
new PremiumCustomerSpecification())
{
}
}
public async Task<int> GetAdultPremiumCustomerCountAsync()
{
return await _customerRepository.CountAsync(
new AdultPremiumCustomerSpecification()
);
}
项目中应用,通过规约查询冷坯、热坯