forked from Avanade/Beef
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRequestCache.cs
85 lines (76 loc) · 3.23 KB
/
RequestCache.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/Beef
using Beef.Entities;
using System;
using System.Collections.Concurrent;
using System.Linq;
namespace Beef.Caching
{
/// <summary>
/// Provides a basic dictionary backed cache for short-lived data within the context of a request scope to reduce data chattiness.
/// </summary>
public class RequestCache : IRequestCache
{
private readonly Lazy<ConcurrentDictionary<Tuple<Type, UniqueKey>, object>> _caching = new(true);
/// <summary>
/// Gets the cached value associated with the specified <see cref="Type"/> and key.
/// </summary>
/// <typeparam name="T">The value <see cref="Type"/>.</typeparam>
/// <param name="key">The key of the value to get.</param>
/// <param name="value">The cached value where found; otherwise, the default value for the <see cref="Type"/>.</param>
/// <returns><c>true</c> where found; otherwise, <c>false</c>.</returns>
public bool TryGetValue<T>(UniqueKey key, out T value)
{
if (_caching.IsValueCreated && _caching.Value.TryGetValue(new Tuple<Type, UniqueKey>(typeof(T), key), out object val))
{
value = (T)val;
return true;
}
value = default!;
return false;
}
/// <summary>
/// Sets (adds or overrides) the cache value for the specified <see cref="Type"/> and key.
/// </summary>
/// <typeparam name="T">The value <see cref="Type"/>.</typeparam>
/// <param name="key">The key of the value to set.</param>
/// <param name="value">The value to set.</param>
public void SetValue<T>(UniqueKey key, T value)
{
_caching.Value.AddOrUpdate(new Tuple<Type, UniqueKey>(typeof(T), key), value!, (x, y) => value!);
}
/// <summary>
/// Removes the cached value associated with the specified <see cref="Type"/> and key.
/// </summary>
/// <typeparam name="T">The value <see cref="Type"/>.</typeparam>
/// <param name="key">The key of the value to remove.</param>
/// <returns><c>true</c> where found and removed; otherwise, <c>false</c>.</returns>
public bool Remove<T>(UniqueKey key)
{
if (_caching.IsValueCreated)
return _caching.Value.TryRemove(new Tuple<Type, UniqueKey>(typeof(T), key), out object _);
else
return false;
}
/// <summary>
/// Clears the cache for the specified <see cref="Type"/>.
/// </summary>
/// <typeparam name="T">The value <see cref="Type"/>.</typeparam>
public void Clear<T>()
{
if (!_caching.IsValueCreated)
return;
foreach (var item in _caching.Value.Where(x => x.Key.Item1 == typeof(T)).ToList())
{
_caching.Value.TryRemove(item.Key, out object val);
}
}
/// <summary>
/// Clears the cache for all <see cref="Type">types</see>.
/// </summary>
public void ClearAll()
{
if (_caching.IsValueCreated)
_caching.Value.Clear();
}
}
}