/// <summary> /// <typeparamref name="TEntity"/> の述語デリゲートを作成します。 /// 既定の実装では <see cref="Create(TContext, ref bool)"/> に処理を委譲します。 /// </summary> /// <param name="context">パイプラインの実行時コンテキスト。常に非 <c>null</c>。</param> /// <param name="next">パイプラインの後続のコンポーネントを表すデリゲート。常に非 <c>null</c>。呼ばない事により残りのコンポーネントをショートサーキットできます。</param> /// <returns>このコンポーネント以降の述語処理を表すデリゲート。常に非 <c>null</c>。</returns> protected virtual Task <PredicateFunc <TEntity> > CreateAsync(TContext context, Func <TContext, Task <PredicateFunc <TEntity> > > next) { Debug.Assert(context != null); Debug.Assert(next != null); var cancelled = false; PredicateFunc <TEntity> predicate = Create(context, ref cancelled); Debug.Assert(predicate != null); if (cancelled) { return(Task.FromResult(predicate)); } if (predicate == NullPredicate) { return(next(context)); } return(InternalAsync()); async Task <PredicateFunc <TEntity> > InternalAsync() { PredicateFunc <TEntity> nextPredicate = await next(context).ConfigureAwait(false); Debug.Assert(nextPredicate != null); if (nextPredicate == NullPredicate) { return(predicate); } return(x => predicate(x) && nextPredicate(x)); } }
public void CreateAsync_Cancelled() { PredicateFunc <DummyEntity> createResult = _ => Rand.Bool(); var middleware = new SpyPredicateMiddlewareToCreateAsync(createResult, cancelled: true); var context = new DummyContext(); Func <DummyContext, Task <PredicateFunc <DummyEntity> > > next = _ => throw new AssertFailedException("next は呼ばれてはいけません。"); new TestCaseRunner() .Run(() => middleware.CreateAsync(context, next)) .Verify((actual, desc) => { Assert.AreEqual(createResult, actual, desc); Assert.AreEqual(context, middleware.ActualContext, desc); Assert.AreEqual(false, middleware.ActualCancelled, desc); }, (Type)null); }
public void Invoke() { PredicateFunc <DummyEntity> createAsyncResult = _ => Rand.Bool(); var middleware = new SpyPredicateMiddlewareToMiddleware(createAsyncResult); Func <DummyContext, Task <PredicateFunc <DummyEntity> > > next = _ => Task.FromResult <PredicateFunc <DummyEntity> >(__ => Rand.Bool()); var context = new DummyContext(); new TestCaseRunner() .Run(() => middleware.Invoke(next)(context)) .Verify((actual, desc) => { Assert.AreEqual(createAsyncResult, actual, desc); Assert.AreEqual(context, middleware.ActualContext, desc); Assert.AreEqual(next, middleware.ActualNext, desc); }, (Type)null); }
public void CreateAsync_NullNextPredicate() { PredicateFunc <DummyEntity> createResult = _ => Rand.Bool(); var middleware = new SpyPredicateMiddlewareToCreateAsync(createResult, cancelled: false); var context = new DummyContext(); DummyContext actualNextContext = default; Func <DummyContext, Task <PredicateFunc <DummyEntity> > > next = ctx => { actualNextContext = ctx; return(Task.FromResult(SpyPredicateMiddlewareToCreateAsync.NullPredicate)); }; new TestCaseRunner() .Run(() => middleware.CreateAsync(context, next)) .Verify((actual, desc) => { Assert.AreEqual(createResult, actual, desc); Assert.AreEqual(context, middleware.ActualContext, desc); Assert.AreEqual(false, middleware.ActualCancelled, desc); Assert.AreEqual(context, actualNextContext, desc); }, (Type)null); }
/// <summary> /// <see cref="IMiddleware{T, TResult}.Invoke(Func{T, TResult})"/> の実装。 /// </summary> public Func <TContext, Task <FilterFunc <TEntity> > > Invoke(Func <TContext, Task <FilterFunc <TEntity> > > next) { Debug.Assert(next != null); return(async context => { Debug.Assert(context != null); PredicateFunc <TEntity> predicate = await _predicateCreator(context).ConfigureAwait(false); Debug.Assert(predicate != null); FilterFunc <TEntity> nextFilter = await next(context).ConfigureAwait(false); Debug.Assert(nextFilter != null); if (predicate == PredicateMiddleware <TContext, TEntity> .NullPredicate) { return nextFilter; } var predicateFunc = new Func <TEntity, bool>(predicate); return source => nextFilter(source.Where(predicateFunc)); }); }
/// <summary> /// Returns <c>true</c> if the given target matches the specified filter. /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="target"></param> /// <param name="filter"></param> /// <returns></returns> public static bool Matches <TSource>(TSource target, JObject filter) { return(filter != null?PredicateFunc <TSource>(filter)(target) : true); }
public SpyPredicateCreator(PredicateFunc <DummyEntity> predicate) => _predicate = predicate;