這一次似乎是矯枉過正,我(但我想這是出現在評論多態性),但無論如何, ,還有它是:
我們先從一個接口:
public interface IQueryFilter
{
IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria);
}
然後實現共同財產:
public abstract class AQueryFilter<T> : IQueryFilter
{
public AQueryFilter(Func<SearchCriteria, T> criteria)
{
Criteria = criteria;
}
protected Func<SearchCriteria, T> Criteria { get; }
public abstract IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria);
}
最後,所有具體的東西:
public class WhereEventStatusQueryFilter : AQueryFilter<bool>
{
private EventStatus _toTest;
public WhereEventStatusQueryFilter(Func<SearchCriteria, bool> criteria, EventStatus toTest)
: base(criteria)
{
_toTest = toTest;
}
public override IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria)
{
return (Criteria(searchCriteria) ? query : query.Where(x => x.EventStatusId != _toTest));
}
}
public class SearchQueryFilter : AQueryFilter<object>
{
Func<Whatever, object> _searchFor;
public SearchQueryFilter(Func<SearchCriteria, object> criteria, Func<Whatever, object> searchFor)
: base(criteria)
{
_searchFor = searchFor;
}
public override IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria)
{
return (Criteria(searchCriteria) == null ? query : query.Search(x => _searchFor(x), Criteria(searchCriteria)));
}
}
public class WhereEqualQueryFilter : AQueryFilter<object>
{
Func<Whatever, object> _searchFor;
public WhereEqualQueryFilter(Func<SearchCriteria, object> criteria, Func<Whatever, object> searchFor)
: base(criteria)
{
_searchFor = searchFor;
}
public override IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria)
{
return (Criteria(searchCriteria) == null ? query : query.Where(x => _searchFor(x) == Criteria(searchCriteria)));
}
}
用法:
var filters = new IQueryFilter[]
{
new WhereEventStatusQueryFilter(x => x.PendingEvent, EventStatus.Pending),
new WhereEventStatusQueryFilter(x => x.VerifiedEvent, EventStatus.Verified),
new SearchQueryFilter(x => x.EventReference, x => x.EventReference),
new WhereEqualQueryFilter(x => x.RemittedId, x => x.Trade.RemittedId),
...
};
foreach (var filter in filters)
query = filter.Filter(query, searchCriteria);
但這種方法隱藏了很多的邏輯。如果有人想添加一些內容,他必須閱讀所有以前的過濾器類,以瞭解是否已有可以完成工作或者必須編寫另一個過濾器的類。
這是一個很好的問題:http://codereview.stackexchange.com –
對象編程與否,這是構建動態過濾器的正確方法。您可以隨時將大方法的某些部分提取到自己的方法中,就像任何常規方法重構一樣,「Where」和「IQueryable」沒有什麼共同之處。 –
如果你想關注的行數,然後從'if'條件中刪除'{}'括號,你會減少兩條線,每個條件:) –