Skip to content

Commit 33d055c

Browse files
talmrothTom Almroth
andauthored
Add TryGetValue (#142)
Co-authored-by: Tom Almroth <[email protected]>
1 parent 8d4b269 commit 33d055c

File tree

7 files changed

+55
-10
lines changed

7 files changed

+55
-10
lines changed

LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ private static CachingService BuildCache()
3232

3333
private class ComplexTestObject
3434
{
35-
public readonly IList<object> SomeItems = new List<object> {1, 2, 3, "testing123"};
35+
public readonly IList<object> SomeItems = new List<object> { 1, 2, 3, "testing123" };
3636
public string SomeMessage = "testing123";
3737
}
3838

@@ -528,7 +528,7 @@ public async Task
528528
Thread.Sleep(500);
529529

530530
Assert.That(callbackValue, Is.AssignableTo<Task<int>>());
531-
var callbackResultValue = await (Task<int>) callbackValue;
531+
var callbackResultValue = await (Task<int>)callbackValue;
532532
Assert.AreEqual(123, callbackResultValue);
533533
}
534534

@@ -873,7 +873,7 @@ MemoryCacheEntryOptions GetOptions()
873873
.SetAbsoluteExpiration(refreshInterval, ExpirationMode.ImmediateEviction);
874874
options.RegisterPostEvictionCallback((keyEvicted, value, reason, state) =>
875875
{
876-
if (reason == EvictionReason.Expired || reason == EvictionReason.TokenExpired)
876+
if (reason == EvictionReason.Expired || reason == EvictionReason.TokenExpired)
877877
sut.GetOrAdd(key, _ => GetStuff(), GetOptions());
878878
});
879879
return options;
@@ -946,7 +946,7 @@ ComplexTestObject GetStuff()
946946
{
947947
var key = $"stuff-{hits % uniqueCacheItems}";
948948
var cached = await sut.GetOrAddAsync(key, () => GetStuffAsync(), DateTimeOffset.UtcNow.AddSeconds(1));
949-
if(!cancel.IsCancellationRequested) Interlocked.Increment(ref hits);
949+
if (!cancel.IsCancellationRequested) Interlocked.Increment(ref hits);
950950
}
951951
});
952952
});
@@ -1108,5 +1108,22 @@ public void RemovedItemCannotBeRetrievedFromCache()
11081108
sut.Remove(TestKey);
11091109
Assert.Null(sut.Get<object>(TestKey));
11101110
}
1111+
1112+
[Test]
1113+
public void TryGetReturnsCachedValueAndTrue()
1114+
{
1115+
string val = "Test Value";
1116+
string key = "testkey";
1117+
sut.Add(key, val);
1118+
1119+
var contains = sut.TryGetValue<string>(key, out var value);
1120+
1121+
Assert.IsTrue(contains);
1122+
Assert.AreEqual(value, val);
1123+
1124+
var contains2 = sut.TryGetValue<string>("invalidkey", out var value2);
1125+
1126+
Assert.IsFalse(contains2);
1127+
}
11111128
}
11121129
}

LazyCache/CachingService.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public CachingService(ICacheProvider cache) : this(() => cache)
4141
}
4242

4343
public static Lazy<ICacheProvider> DefaultCacheProvider { get; set; }
44-
= new Lazy<ICacheProvider>(() =>
44+
= new Lazy<ICacheProvider>(() =>
4545
new MemoryCacheProvider(
4646
new MemoryCache(
4747
new MemoryCacheOptions())
@@ -89,6 +89,13 @@ public virtual Task<T> GetAsync<T>(string key)
8989
return GetValueFromAsyncLazy<T>(item, out _);
9090
}
9191

92+
public virtual bool TryGetValue<T>(string key, out object value)
93+
{
94+
ValidateKey(key);
95+
96+
return CacheProvider.TryGetValue(key, out value);
97+
}
98+
9299
public virtual T GetOrAdd<T>(string key, Func<ICacheEntry, T> addItemFactory)
93100
{
94101
return GetOrAdd(key, addItemFactory, null);
@@ -112,7 +119,7 @@ object CacheFactory(ICacheEntry entry) =>
112119
// acquire lock per key
113120
uint hash = (uint)key.GetHashCode() % (uint)keyLocks.Length;
114121
while (Interlocked.CompareExchange(ref keyLocks[hash], 1, 0) == 1) { Thread.Yield(); }
115-
122+
116123
try
117124
{
118125
cacheItem = CacheProvider.GetOrCreate<object>(key, policy, CacheFactory);
@@ -179,7 +186,7 @@ public virtual Task<T> GetOrAddAsync<T>(string key, Func<ICacheEntry, Task<T>> a
179186

180187
public virtual async Task<T> GetOrAddAsync<T>(string key, Func<ICacheEntry, Task<T>> addItemFactory,
181188
MemoryCacheEntryOptions policy)
182-
{
189+
{
183190
ValidateKey(key);
184191

185192
object cacheItem;
@@ -280,7 +287,7 @@ protected virtual T GetValueFromLazy<T>(object item, out bool valueHasChangedTyp
280287

281288
protected virtual Task<T> GetValueFromAsyncLazy<T>(object item, out bool valueHasChangedType)
282289
{
283-
valueHasChangedType = false;
290+
valueHasChangedType = false;
284291
switch (item)
285292
{
286293
case AsyncLazy<T> asyncLazy:

LazyCache/IAppCache.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public interface IAppCache
1515
void Add<T>(string key, T item, MemoryCacheEntryOptions policy);
1616
T Get<T>(string key);
1717
Task<T> GetAsync<T>(string key);
18+
bool TryGetValue<T>(string key, out object value);
19+
1820
T GetOrAdd<T>(string key, Func<ICacheEntry, T> addItemFactory);
1921
T GetOrAdd<T>(string key, Func<ICacheEntry, T> addItemFactory, MemoryCacheEntryOptions policy);
2022
Task<T> GetOrAddAsync<T>(string key, Func<ICacheEntry, Task<T>> addItemFactory);

LazyCache/ICacheProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ public interface ICacheProvider : IDisposable
1212
object GetOrCreate<T>(string key, MemoryCacheEntryOptions policy, Func<ICacheEntry, T> func);
1313
void Remove(string key);
1414
Task<T> GetOrCreateAsync<T>(string key, Func<ICacheEntry, Task<T>> func);
15+
bool TryGetValue(object key, out object value);
1516
}
1617
}

LazyCache/Mocks/MockCacheProvider.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace LazyCache.Mocks
66
{
7+
78
public class MockCacheProvider : ICacheProvider
89
{
910
public void Set(string key, object item, MemoryCacheEntryOptions policy)
@@ -34,6 +35,11 @@ public Task<T> GetOrCreateAsync<T>(string key, Func<ICacheEntry, Task<T>> func)
3435
return func(null);
3536
}
3637

38+
public bool TryGetValue(object key, out object value)
39+
{
40+
throw new NotImplementedException();
41+
}
42+
3743
public void Dispose()
3844
{
3945
}

LazyCache/Mocks/MockCachingService.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,11 @@ public Task<T> GetAsync<T>(string key)
5151
public void Add<T>(string key, T item, MemoryCacheEntryOptions policy)
5252
{
5353
}
54+
55+
public bool TryGetValue<T>(string key, out object value)
56+
{
57+
value = default(T);
58+
return true;
59+
}
5460
}
5561
}

LazyCache/Providers/MemoryCacheProvider.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public object GetOrCreate<T>(string key, Func<ICacheEntry, T> factory)
3232

3333
public object GetOrCreate<T>(string key, MemoryCacheEntryOptions policy, Func<ICacheEntry, T> factory)
3434
{
35-
if(policy == null)
35+
if (policy == null)
3636
return cache.GetOrCreate(key, factory);
3737

3838
if (!cache.TryGetValue(key, out var result))
@@ -47,7 +47,7 @@ public object GetOrCreate<T>(string key, MemoryCacheEntryOptions policy, Func<IC
4747
var expiryTokenSource = new CancellationTokenSource();
4848
var expireToken = new CancellationChangeToken(expiryTokenSource.Token);
4949
entry.AddExpirationToken(expireToken);
50-
entry.RegisterPostEvictionCallback((keyPost, value, reason, state) =>
50+
entry.RegisterPostEvictionCallback((keyPost, value, reason, state) =>
5151
expiryTokenSource.Dispose());
5252

5353
result = factory(entry);
@@ -78,6 +78,12 @@ public Task<T> GetOrCreateAsync<T>(string key, Func<ICacheEntry, Task<T>> factor
7878
return cache.GetOrCreateAsync(key, factory);
7979
}
8080

81+
public bool TryGetValue(object key, out object value)
82+
{
83+
return cache.TryGetValue(key, out value);
84+
}
85+
86+
8187
public void Dispose()
8288
{
8389
cache?.Dispose();

0 commit comments

Comments
 (0)