Pdsr.Cache.NoCache
4.1.0
dotnet add package Pdsr.Cache.NoCache --version 4.1.0
NuGet\Install-Package Pdsr.Cache.NoCache -Version 4.1.0
<PackageReference Include="Pdsr.Cache.NoCache" Version="4.1.0" />
<PackageVersion Include="Pdsr.Cache.NoCache" Version="4.1.0" />
<PackageReference Include="Pdsr.Cache.NoCache" />
paket add Pdsr.Cache.NoCache --version 4.1.0
#r "nuget: Pdsr.Cache.NoCache, 4.1.0"
#:package Pdsr.Cache.NoCache@4.1.0
#addin nuget:?package=Pdsr.Cache.NoCache&version=4.1.0
#tool nuget:?package=Pdsr.Cache.NoCache&version=4.1.0
Pdsr Cache Helper
A helper library (wrapper) for caching with Redis, MSSQL, ...
What is it?
I have started building several libraries to keep up with the DRY principle, one of them was this lib, helping me to use cache systems.
The first goal this library is keeping Cache requests in one go so I don't have to check if the cache exists, if the cache time has passed, etc.
Getting Started
you need to install the package, add to DI and then use it in services.
- install the package
dotnet add package Pdsr.Cache.Redisfor Redis. - Add the
RedisCacheManagerto DI through the extensionAddRedisCacheManager(c => { c.EndPoints = ["my-redis:6379"]; c.KeyPrefix = "my-app:"; }) - Instantiate the
ICacheManagerin your controller or service. - Use any of the Get,Set, ... methods. Async or Sync.
public class MyClass
{
private readonly ICacheManager _cache;
public MyClass(ICacheManager cache) => _cache = cache;
public async Task SomeMethod(CancellationToken cancellationToken = default)
{
var results = await _cache.GetAsync<SomeModel>(
"some-key" , // cache key identifier
async () => // Func<Task<T>> to produce something
{
var model = new SomeModel(); // produce something time consuming
return model;
},
60, // cache time
cancellationToken);
return results;
}
}
Reading a value that may be missing
Use TryGet/TryGetAsync instead of IsSet followed by Get. The two-step version can race with expiry,
and Get returns default on a miss, so a cached false and "not cached" look the same.
var cached = await _cache.TryGetAsync<bool>($"access:{userId}", cancellationToken);
if (cached.HasValue)
return cached.Value;
When Redis is down
Reads, writes and IsSet throw (RedisConnectionException or RedisTimeoutException) instead of reporting a miss.
The read-through overloads that take an acquire delegate fall back to it and return a correct, uncached value.
How long a call takes to fail depends on FailFastWhenDisconnected:
| Setting | While disconnected, each call | Read-through with acquire |
|---|---|---|
false (default) |
waits in the client's queue for AsyncTimeout/SyncTimeout (5 s unless set), then throws |
waits the timeout on the read, then calls acquire |
true |
throws RedisConnectionException immediately |
calls acquire immediately |
Turn it on when the cache is an optimisation and callers fall back to the source: otherwise every request pays the
timeout for as long as the outage lasts. Leave it off if you'd rather ride out short reconnects, since queued commands
are sent once the connection is back instead of failing. Either way you can bound the wait with AsyncTimeout and
SyncTimeout (milliseconds).
services.AddRedisCacheManager(c =>
{
c.EndPoints = ["my-redis:6379"];
c.FailFastWhenDisconnected = true; // fail immediately during an outage
c.AsyncTimeout = 1000; // and give up on a slow command after 1 s
});
The first connect is separate. Calls made while the first connection attempt is still running wait for that attempt
(around 2 s against a host that refuses connections, up to the client's ConnectTimeout against one that doesn't answer).
After a failed attempt, with AbortOnConnectFail = false, the client keeps retrying in the background and calls follow the
table above.
FailFastWhenDisconnected, AsyncTimeout and SyncTimeout live on IRedisTimeoutConfiguration, which
RedisConfiguration implements. A custom IRedisConfiguration keeps the client defaults unless it implements that interface too.
Cancellation
Every async method takes a CancellationToken. Cancelling it stops the caller waiting and throws OperationCanceledException,
but it can't recall a command that was already sent to Redis or SQL Server. That command may still run,
so a cancelled SetAsync or RemoveAsync can still write or delete the key. A token that is already cancelled is rejected
before anything is sent.
Sharing a Redis server
Set KeyPrefix so each application has its own keyspace. With a prefix, Clear and RemoveByPattern
only touch that application's keys. Without one, Clear refuses to run FLUSHDB unless AllowFlushDatabase is set.
Changes in 4.1
- New
FailFastWhenDisconnected,AsyncTimeoutandSyncTimeoutsettings control how long calls wait while Redis is unreachable (see "When Redis is down"). They're opt-in, so 4.0's behaviour is unchanged unless you set them. - They're on a new optional interface,
IRedisTimeoutConfiguration, so existingIRedisConfigurationimplementations keep compiling.
Upgrading to 4.0
4.0 is a breaking release:
ISyncCacheManager.TryGetandIAsyncCacheManager.TryGetAsyncwere added; custom implementations must add them.- Redis outages now throw instead of returning
default/false(see above). IRedisConnectionFactoryreturnsIConnectionMultiplexer, addsConnectionAsync, and owns the connection; disposing a cache manager no longer closes it.RedisConfiguration: obsoleteHost/Portremoved;UseCallingAssemblyNameAsClientNamerenamed toUseEntryAssemblyNameAsClientName;RetryCount,Database,KeyPrefixandAllowFlushDatabaseadded. Host names are no longer resolved to fixed IPs at startup.- Redis
Clearno longer flushes the database by default. Set<T>(key, data, TimeSpan? expiry)no longer has a default forexpiry; the RedisGet/GetAsyncpreferReplicaparameter is now required.- Redis sets:
RemoveFromSetItemAsyncis nowRemoveFromSetAsyncand also deletes the item;GetSetLengthis nowGetSetLengthAsync;GetSetItemsAsyncleaves out expired items. - A zero or negative cache time now means "don't cache" in every provider.
InMemoryCacheConfig.MaxEnteriesCountis nowMaxEntriesCount; in-memory patterns use Redis glob syntax instead of regex.SqlCacheManager.RemoveByPattern/ClearthrowNotSupportedException.- DI extension classes were renamed (
RedisServiceCollectionExtensions, …); the extension methods themselves are unchanged except that the Redis service lifetime parameters were removed (everything is a singleton). - Removed:
Pdsr.Cache.Polly,ICacheManagerExtendedandRedisCacheManagerExtended, and the non-genericSet/SetAsync/Getoverloads.
Contribute
Please refer to contribute. Some parts definitely needs help.
Documents
Under Creation.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Pdsr.Cache (>= 4.1.0)
-
.NETStandard 2.1
- Pdsr.Cache (>= 4.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.1.0 | 115 | 10/16/2026 |
| 4.0.0 | 99 | 10/6/2026 |
| 4.0.0-beta.4 | 64 | 10/6/2026 |
| 4.0.0-beta.3 | 64 | 10/6/2026 |
| 4.0.0-beta.2 | 73 | 10/6/2026 |
| 4.0.0-beta.1 | 63 | 10/6/2026 |
| 3.6.0 | 359 | 2/13/2025 |
| 3.5.1 | 296 | 10/9/2024 |
| 3.5.1-beta.1 | 158 | 10/9/2024 |
| 3.5.0 | 344 | 2/20/2024 |
| 3.3.1 | 333 | 8/26/2023 |
| 3.3.0 | 334 | 7/18/2023 |
| 3.2.1 | 442 | 2/20/2023 |
| 3.2.0 | 526 | 11/11/2022 |
| 3.1.8 | 637 | 9/13/2022 |
| 3.0.7 | 611 | 8/25/2022 |
| 3.0.6 | 642 | 6/21/2022 |
| 3.0.5 | 694 | 5/11/2022 |
| 3.0.4 | 706 | 4/18/2022 |
| 3.0.3 | 675 | 4/18/2022 |