From 7d065953070f9fcc8fa5f8893323222bc960862a Mon Sep 17 00:00:00 2001 From: Alex Macocian Date: Thu, 26 Sep 2024 10:32:38 +0200 Subject: [PATCH] Implement value caches --- .../SystemExtensions.NetCore.csproj | 2 +- .../Cache/AsyncValueCache.cs | 36 +++++++++++++++++++ .../Cache/ValueCache.cs | 35 ++++++++++++++++++ .../SystemExtensions.NetStandard.csproj | 2 +- 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 SystemExtensions.NetStandard/Cache/AsyncValueCache.cs create mode 100644 SystemExtensions.NetStandard/Cache/ValueCache.cs diff --git a/SystemExtensions.NetCore/SystemExtensions.NetCore.csproj b/SystemExtensions.NetCore/SystemExtensions.NetCore.csproj index cd68814..a2411e2 100644 --- a/SystemExtensions.NetCore/SystemExtensions.NetCore.csproj +++ b/SystemExtensions.NetCore/SystemExtensions.NetCore.csproj @@ -8,7 +8,7 @@ System LICENSE true - 1.6.8 + 1.6.9 Alexandru Macocian https://github.com/AlexMacocian/SystemExtensions Extensions for the System namespace diff --git a/SystemExtensions.NetStandard/Cache/AsyncValueCache.cs b/SystemExtensions.NetStandard/Cache/AsyncValueCache.cs new file mode 100644 index 0000000..c901cad --- /dev/null +++ b/SystemExtensions.NetStandard/Cache/AsyncValueCache.cs @@ -0,0 +1,36 @@ +using System.Extensions; +using System.Threading.Tasks; + +namespace System.Cache; +public sealed class AsyncValueCache(Func> cacheRefreshOperation, TimeSpan cacheDuration) + where T : class +{ + private readonly Func> cacheRefreshOperation = cacheRefreshOperation.ThrowIfNull(nameof(cacheRefreshOperation)); + private readonly TimeSpan cacheDuration = cacheDuration; + + private T? value; + private DateTime lastCacheRefresh = DateTime.MinValue; + + public async Task GetValue() + { + if (DateTime.Now - this.lastCacheRefresh < this.cacheDuration && + this.value is not null) + { + return this.value; + } + + return await this.PerformCacheRefresh(); + } + + public async Task ForceCacheRefresh() + { + return await this.PerformCacheRefresh(); + } + + private async Task PerformCacheRefresh() + { + this.value = await this.cacheRefreshOperation(); + this.lastCacheRefresh = DateTime.Now; + return this.value; + } +} diff --git a/SystemExtensions.NetStandard/Cache/ValueCache.cs b/SystemExtensions.NetStandard/Cache/ValueCache.cs new file mode 100644 index 0000000..1f8df85 --- /dev/null +++ b/SystemExtensions.NetStandard/Cache/ValueCache.cs @@ -0,0 +1,35 @@ +using System.Extensions; + +namespace System.Cache; +public sealed class ValueCache(Func cacheRefreshOperation, TimeSpan cacheDuration) + where T : class +{ + private readonly Func cacheRefreshOperation = cacheRefreshOperation.ThrowIfNull(nameof(cacheRefreshOperation)); + private readonly TimeSpan cacheDuration = cacheDuration; + + private T? value; + private DateTime lastCacheRefresh = DateTime.MinValue; + + public T GetValue() + { + if (DateTime.Now - this.lastCacheRefresh < this.cacheDuration && + this.value is not null) + { + return this.value; + } + + return this.PerformCacheRefresh(); + } + + public T ForceCacheRefresh() + { + return this.PerformCacheRefresh(); + } + + private T PerformCacheRefresh() + { + this.value = this.cacheRefreshOperation(); + this.lastCacheRefresh = DateTime.Now; + return this.value; + } +} diff --git a/SystemExtensions.NetStandard/SystemExtensions.NetStandard.csproj b/SystemExtensions.NetStandard/SystemExtensions.NetStandard.csproj index 6e1456a..91eb33b 100644 --- a/SystemExtensions.NetStandard/SystemExtensions.NetStandard.csproj +++ b/SystemExtensions.NetStandard/SystemExtensions.NetStandard.csproj @@ -7,7 +7,7 @@ LICENSE true System - 1.6.8 + 1.6.9 Alexandru Macocian https://github.com/AlexMacocian/SystemExtensions Extensions for the System namespace