是否有任何健壮、优雅和/或标准的方式来实现内存中集合(IEnumerable<T>
而不是IQueryable<T>
)的规范模式,包括塑造/投影结果?
使用Func<T, bool>
for 标准显然只涵盖Where
子句/方法,而不是Select
.
到目前为止,我想出的想法是我可以在我的规范中包含另一个委托(不是双关语)专门涵盖该Select
操作。实现可能如下所示。正如您在底部看到的那样,存储库只是简单地执行Where
and Select
,并传入规范的委托成员。
这个解决方案似乎工作得很好,但我在很多场合发现我正在解决的问题存在现有的更好的解决方案,所以问这个问题似乎是合理的。
(我计划使用规范模式的原因是,我的应用程序可能需要从复杂对象的内存集合中以各种形状显示大量结果,并且将查询内容保持在一个单一的,易于查找/管理的地方。但请随意提出完全不同的建议。)
internal interface IMySpecification<TEntity, TResult>
{
Func<TEntity, bool> Where { get; }
Func<TEntity, TResult> Select { get; }
bool IsSatisfiedBy(TEntity t);
// ...
}
internal interface IMyRepository<TEntity>
{
// ...
TResult GetSingle<TResult>(IMySpecification<TEntity, TResult> spec);
IEnumerable<TResult> List<TResult>(IMySpecification<TEntity, TResult> spec);
}
internal class MyGenericRepository<T> : IMyRepository<T>
{
protected IEnumerable<T> _collection;
public MyGenericRepository(IEnumerable<T> list)
=> _collection = list;
// ...
public TResult GetSingle<TResult>(IMySpecification<T, TResult> spec)
=> List(spec).Single();
public IEnumerable<TResult> List<TResult>(IMySpecification<T, TResult> spec)
=> (IEnumerable<TResult>)_collection.Where(spec.Where).Select(spec.Select);
}