PredicateBuilder<TResult>
Defines a builder for creating predicates for TResult and Exception combinations.
using Polly.CircuitBreaker;
using Polly.Fallback;
using Polly.Hedging;
using Polly.Retry;
using Polly.Utils;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace Polly
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class PredicateBuilder<[System.Runtime.CompilerServices.Nullable(2)] TResult>
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
0,
1
})]
private readonly List<Predicate<Outcome<TResult>>> _predicates = new List<Predicate<Outcome<TResult>>>();
public static implicit operator Func<RetryPredicateArguments<TResult>, ValueTask<bool>>(PredicateBuilder<TResult> builder)
{
Guard.NotNull<PredicateBuilder<TResult>>(builder, "builder");
return builder.Build<RetryPredicateArguments<TResult>>();
}
public static implicit operator Func<HedgingPredicateArguments<TResult>, ValueTask<bool>>(PredicateBuilder<TResult> builder)
{
Guard.NotNull<PredicateBuilder<TResult>>(builder, "builder");
return builder.Build<HedgingPredicateArguments<TResult>>();
}
public static implicit operator Func<FallbackPredicateArguments<TResult>, ValueTask<bool>>(PredicateBuilder<TResult> builder)
{
Guard.NotNull<PredicateBuilder<TResult>>(builder, "builder");
return builder.Build<FallbackPredicateArguments<TResult>>();
}
public static implicit operator Func<CircuitBreakerPredicateArguments<TResult>, ValueTask<bool>>(PredicateBuilder<TResult> builder)
{
Guard.NotNull<PredicateBuilder<TResult>>(builder, "builder");
return builder.Build<CircuitBreakerPredicateArguments<TResult>>();
}
public PredicateBuilder<TResult> Handle<[System.Runtime.CompilerServices.Nullable(0)] TException>() where TException : Exception
{
return Handle((TException _) => true);
}
public PredicateBuilder<TResult> Handle<[System.Runtime.CompilerServices.Nullable(0)] TException>(Func<TException, bool> predicate) where TException : Exception
{
Guard.NotNull<Func<TException, bool>>(predicate, "predicate");
return this.Add((Predicate<Outcome<TResult>>)delegate(Outcome<TResult> outcome) {
TException val = outcome.Exception as TException;
if (val != null)
return predicate(val);
return false;
});
}
public PredicateBuilder<TResult> HandleInner<[System.Runtime.CompilerServices.Nullable(0)] TException>() where TException : Exception
{
return HandleInner((TException _) => true);
}
public PredicateBuilder<TResult> HandleInner<[System.Runtime.CompilerServices.Nullable(0)] TException>(Func<TException, bool> predicate) where TException : Exception
{
Guard.NotNull<Func<TException, bool>>(predicate, "predicate");
return this.Add((Predicate<Outcome<TResult>>)delegate(Outcome<TResult> outcome) {
TException val = outcome.Exception?.InnerException as TException;
if (val != null)
return predicate(val);
return false;
});
}
public PredicateBuilder<TResult> HandleResult(Func<TResult, bool> predicate)
{
return Add(delegate(Outcome<TResult> outcome) {
if (outcome.TryGetResult(out TResult result))
return predicate(result);
return false;
});
}
public PredicateBuilder<TResult> HandleResult(TResult result, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] IEqualityComparer<TResult> comparer = null)
{
if (comparer == null)
comparer = EqualityComparer<TResult>.Default;
return HandleResult((TResult r) => comparer.Equals(r, result));
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})]
public Predicate<Outcome<TResult>> Build()
{
switch (_predicates.Count) {
case 0:
throw new InvalidOperationException("No predicates were configured. There must be at least one predicate added.");
case 1:
return _predicates[0];
default:
return CreatePredicate(_predicates.ToArray());
}
}
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
0
})]
internal Func<TArgs, ValueTask<bool>> Build<TArgs>() where TArgs : IOutcomeArguments<TResult>
{
Predicate<Outcome<TResult>> predicate = this.Build();
return (TArgs args) => new ValueTask<bool>(predicate(((IOutcomeArguments<TResult>)args).Outcome));
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})]
private static Predicate<Outcome<TResult>> CreatePredicate([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
0,
1
})] Predicate<Outcome<TResult>>[] predicates)
{
return delegate(Outcome<TResult> outcome) {
Predicate<Outcome<TResult>>[] array = predicates;
for (int i = 0; i < array.Length; i++) {
if (array[i](outcome))
return true;
}
return false;
};
}
private PredicateBuilder<TResult> Add([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})] Predicate<Outcome<TResult>> predicate)
{
_predicates.Add(predicate);
return this;
}
}
}