diff --git a/src/Polly/Caching/AsyncCacheTResultSyntax.cs b/src/Polly/Caching/AsyncCacheTResultSyntax.cs index 3aab6b10c20..2ea8180542c 100644 --- a/src/Polly/Caching/AsyncCacheTResultSyntax.cs +++ b/src/Polly/Caching/AsyncCacheTResultSyntax.cs @@ -1,7 +1,6 @@ #nullable enable namespace Polly; -#pragma warning disable CA1062 // Validate arguments of public methods public partial class Policy { /// @@ -63,13 +62,22 @@ public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider /// The policy instance. /// Thrown when is . /// Thrown when is . - public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action? onCacheError = null) + public static AsyncCachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action? onCacheError = null) { if (cacheProvider == null) { throw new ArgumentNullException(nameof(cacheProvider)); } + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + return CacheAsync(cacheProvider.AsyncFor(), new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); } @@ -88,13 +96,22 @@ public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider /// Thrown when is . /// Thrown when is . /// Thrown when is . - public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action? onCacheError = null) + public static AsyncCachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + ICacheKeyStrategy cacheKeyStrategy, + Action? onCacheError = null) { if (cacheProvider == null) { throw new ArgumentNullException(nameof(cacheProvider)); } + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + return CacheAsync(cacheProvider.AsyncFor(), ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheError); } @@ -256,6 +273,11 @@ public static AsyncCachePolicy CacheAsync( throw new ArgumentNullException(nameof(cacheProvider)); } + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + return CacheAsync(cacheProvider.AsyncFor(), new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } @@ -296,6 +318,11 @@ public static AsyncCachePolicy CacheAsync( throw new ArgumentNullException(nameof(cacheProvider)); } + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + return CacheAsync(cacheProvider.AsyncFor(), ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } @@ -439,8 +466,19 @@ public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider< /// The policy instance. /// Thrown when is . /// Thrown when is . - public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action? onCacheError = null) => - CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); + public static AsyncCachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action? onCacheError = null) + { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + + return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); + } /// /// Builds an that will function like a result cache for delegate executions returning a . @@ -457,11 +495,28 @@ public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider< /// Thrown when is . /// Thrown when is . /// Thrown when is . - public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action? onCacheError = null) + public static AsyncCachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + ICacheKeyStrategy cacheKeyStrategy, + Action? onCacheError = null) { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + Action emptyDelegate = (_, _) => { }; - return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + return CacheAsync( + cacheProvider, + ttlStrategy, + cacheKeyStrategy.GetCacheKey, + emptyDelegate, + emptyDelegate, + emptyDelegate, + onCacheError, + onCacheError); } /// @@ -479,11 +534,28 @@ public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider< /// Thrown when is . /// Thrown when is . /// Thrown when is . - public static AsyncCachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action? onCacheError = null) + public static AsyncCachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + ICacheKeyStrategy cacheKeyStrategy, + Action? onCacheError = null) { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + Action emptyDelegate = (_, _) => { }; - return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + return CacheAsync( + cacheProvider, + ttlStrategy, + cacheKeyStrategy.GetCacheKey, + emptyDelegate, + emptyDelegate, + emptyDelegate, + onCacheError, + onCacheError); } /// @@ -666,9 +738,23 @@ public static AsyncCachePolicy CacheAsync( Action onCacheMiss, Action onCachePut, Action? onCacheGetError, - Action? onCachePutError) => - CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, - onCachePut, onCacheGetError, onCachePutError); + Action? onCachePutError) + { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + + return CacheAsync( + cacheProvider, + new RelativeTtl(ttl), + cacheKeyStrategy.GetCacheKey, + onCacheGet, + onCacheMiss, + onCachePut, + onCacheGetError, + onCachePutError); + } /// /// Builds an that will function like a result cache for delegate executions returning a . @@ -700,8 +786,23 @@ public static AsyncCachePolicy CacheAsync( Action onCacheMiss, Action onCachePut, Action? onCacheGetError, - Action? onCachePutError) => - CacheAsync(cacheProvider, ttlStrategy.For(), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + Action? onCachePutError) + { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + + return CacheAsync( + cacheProvider, + ttlStrategy.For(), + cacheKeyStrategy.GetCacheKey, + onCacheGet, + onCacheMiss, + onCachePut, + onCacheGetError, + onCachePutError); + } /// /// Builds an that will function like a result cache for delegate executions returning a . @@ -733,8 +834,23 @@ public static AsyncCachePolicy CacheAsync( Action onCacheMiss, Action onCachePut, Action? onCacheGetError, - Action? onCachePutError) => - CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + Action? onCachePutError) + { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + + return CacheAsync( + cacheProvider, + ttlStrategy, + cacheKeyStrategy.GetCacheKey, + onCacheGet, + onCacheMiss, + onCachePut, + onCacheGetError, + onCachePutError); + } /// /// Builds an that will function like a result cache for delegate executions returning a . diff --git a/test/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs b/test/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs index 8b4b9874d98..a2fa949e837 100644 --- a/test/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs +++ b/test/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs @@ -26,9 +26,85 @@ public void Should_throw_when_ttl_strategy_is_null() public void Should_throw_when_cache_key_strategy_is_null() { IAsyncCacheProvider cacheProvider = new StubCacheProvider(); - Func cacheKeyStrategy = null!; - Action action = () => Policy.CacheAsync(cacheProvider, TimeSpan.MaxValue, cacheKeyStrategy); - action.Should().Throw().And.ParamName.Should().Be("cacheKeyStrategy"); + var ttl = TimeSpan.MaxValue; + ITtlStrategy ttlStrategy = new ContextualTtl(); + ICacheKeyStrategy cacheKeyStrategy = null!; + Func cacheKeyStrategyFunc = null!; + Action onCacheGet = (_, _) => { }; + Action onCacheMiss = (_, _) => { }; + Action onCachePut = (_, _) => { }; + Action? onCacheGetError = null; + Action? onCachePutError = null; + const string CacheKeyStrategyExpected = "cacheKeyStrategy"; + + Action action = () => Policy.CacheAsync(cacheProvider, ttl, cacheKeyStrategy, onCacheGetError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy, onCacheGetError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync(cacheProvider, ttl, cacheKeyStrategyFunc); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync(cacheProvider.AsyncFor(), ttl, cacheKeyStrategy); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync(cacheProvider.AsyncFor(), ttlStrategy, cacheKeyStrategy); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync( + cacheProvider.AsyncFor(), + ttlStrategy.For(), + cacheKeyStrategy, + onCacheGetError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync( + cacheProvider.AsyncFor(), + ttl, + cacheKeyStrategy, + onCacheGetError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync( + cacheProvider.AsyncFor(), + ttl, + cacheKeyStrategy, + onCacheGetError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync( + cacheProvider.AsyncFor(), + ttl, + cacheKeyStrategy, + onCacheGet, + onCacheMiss, + onCachePut, + onCacheGetError, + onCachePutError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync( + cacheProvider.AsyncFor(), + ttlStrategy, + cacheKeyStrategy, + onCacheGet, + onCacheMiss, + onCachePut, + onCacheGetError, + onCachePutError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.CacheAsync( + cacheProvider.AsyncFor(), + ttlStrategy.For(), + cacheKeyStrategy, + onCacheGet, + onCacheMiss, + onCachePut, + onCacheGetError, + onCachePutError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); } #endregion