• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / FluentCommand / 19283036656

12 Nov 2025 01:06AM UTC coverage: 55.036% (-0.2%) from 55.189%
19283036656

push

github

pwelter34
fix build

1737 of 3650 branches covered (47.59%)

Branch coverage included in aggregate %.

4372 of 7450 relevant lines covered (58.68%)

331.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.27
/src/FluentCommand.Caching/DistributedDataCache.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Threading;
5

6
using Microsoft.Extensions.Caching.Distributed;
7
using Microsoft.Extensions.Logging;
8

9
namespace FluentCommand.Caching;
10

11
/// <summary>
12
/// Distributed data cache implementation
13
/// </summary>
14
/// <seealso cref="FluentCommand.IDataCache" />
15
public partial class DistributedDataCache : IDataCache
16
{
17
    private readonly ILogger<DistributedDataCache> _logger;
18
    private readonly IDistributedCache _distributedCache;
19
    private readonly IDistributedCacheSerializer _distributedCacheSerializer;
20

21
    /// <summary>
22
    /// Initializes a new instance of the <see cref="DistributedDataCache"/> class.
23
    /// </summary>
24
    /// <param name="logger">The logger.</param>
25
    /// <param name="distributedCache">The distributed cache.</param>
26
    /// <param name="distributedCacheSerializer">The distributed cache serializer.</param>
27
    public DistributedDataCache(ILogger<DistributedDataCache> logger, IDistributedCache distributedCache, IDistributedCacheSerializer distributedCacheSerializer)
1✔
28
    {
29
        _logger = logger;
1✔
30
        _distributedCache = distributedCache;
1✔
31
        _distributedCacheSerializer = distributedCacheSerializer;
1✔
32
    }
1✔
33

34
    /// <summary>
35
    /// Gets the specified cache entry from the cache as an object.
36
    /// </summary>
37
    /// <typeparam name="T">The type of item in cache</typeparam>
38
    /// <param name="key">A unique identifier for the cache entry.</param>
39
    /// <returns>
40
    /// <para>Success is true if the key was found; otherwise false</para>
41
    /// <para>Value is the cache entry that is identified by key</para>
42
    /// </returns>
43
    /// <exception cref="System.ArgumentException">key cannot be null or empty. - key</exception>
44
    public (bool Success, T Value) Get<T>(string key)
45
    {
46
        if (string.IsNullOrEmpty(key))
2!
47
            throw new ArgumentException($"'{nameof(key)}' cannot be null or empty.", nameof(key));
×
48

49
        var cachedBuffer = _distributedCache.Get(key);
2✔
50

51
        if (cachedBuffer == null)
2!
52
        {
53
            LogCacheMiss(_logger, key);
×
54
            return (false, default);
×
55
        }
56

57
        var cachedItem = _distributedCacheSerializer.Deserialize<T>(cachedBuffer);
2✔
58

59
        LogCacheHit(_logger, key);
2✔
60

61
        return (true, cachedItem);
2✔
62
    }
63

64
    /// <summary>
65
    /// Gets the specified cache entry from the cache as an object.
66
    /// </summary>
67
    /// <typeparam name="T">The type of item in cache</typeparam>
68
    /// <param name="key">A unique identifier for the cache entry.</param>
69
    /// <param name="cancellationToken">The cancellation instruction.</param>
70
    /// <returns>
71
    /// <para>Success is true if the key was found; otherwise false</para>
72
    /// <para>Value is the cache entry that is identified by key</para>
73
    /// </returns>
74
    /// <exception cref="System.ArgumentException">'key' cannot be null or empty. - key</exception>
75
    public async Task<(bool Success, T Value)> GetAsync<T>(string key, CancellationToken cancellationToken = default)
76
    {
77
        if (string.IsNullOrEmpty(key))
4!
78
            throw new ArgumentException($"'{nameof(key)}' cannot be null or empty.", nameof(key));
×
79

80
        var cachedBuffer = await _distributedCache
4✔
81
            .GetAsync(key, cancellationToken)
4✔
82
            .ConfigureAwait(false);
4✔
83

84
        if (cachedBuffer == null)
4✔
85
        {
86
            LogCacheMiss(_logger, key);
2✔
87
            return (false, default);
2✔
88
        }
89

90
        var cachedItem = await _distributedCacheSerializer
2✔
91
            .DeserializeAsync<T>(cachedBuffer, cancellationToken)
2✔
92
            .ConfigureAwait(false);
2✔
93

94
        LogCacheHit(_logger, key);
2✔
95

96
        return (true, cachedItem);
2✔
97
    }
4✔
98

99
    /// <summary>
100
    /// Inserts a cache entry into the cache, specifying information about how the entry will be evicted.
101
    /// </summary>
102
    /// <typeparam name="T">The type of item in cache</typeparam>
103
    /// <param name="key">A unique identifier for the cache entry.</param>
104
    /// <param name="value">The object to insert into cache.</param>
105
    /// <param name="absoluteExpiration">The fixed date and time at which the cache entry will expire.</param>
106
    /// <param name="slidingExpiration">A value that indicates whether a cache entry should be evicted if it has not been accessed in a given span of time.</param>
107
    /// <exception cref="System.ArgumentException">'key' cannot be null or empty. - key</exception>
108
    /// <exception cref="System.ArgumentNullException">value</exception>
109
    public void Set<T>(string key, T value, DateTimeOffset? absoluteExpiration = null, TimeSpan? slidingExpiration = null)
110
    {
111
        if (string.IsNullOrEmpty(key))
×
112
            throw new ArgumentException($"'{nameof(key)}' cannot be null or empty.", nameof(key));
×
113

114
        if (value is null)
×
115
            throw new ArgumentNullException(nameof(value));
×
116

117
        var itemBuffer = _distributedCacheSerializer.Serialize(value);
×
118

119
        var distributedOptions = new DistributedCacheEntryOptions
×
120
        {
×
121
            AbsoluteExpiration = absoluteExpiration,
×
122
            SlidingExpiration = slidingExpiration
×
123
        };
×
124

125
        _distributedCache.Set(key, itemBuffer, distributedOptions);
×
126

127
        LogCacheInsert(_logger, key);
×
128
    }
×
129

130
    /// <summary>
131
    /// Inserts a cache entry into the cache, specifying information about how the entry will be evicted.
132
    /// </summary>
133
    /// <typeparam name="T">The type of item in cache</typeparam>
134
    /// <param name="key">A unique identifier for the cache entry.</param>
135
    /// <param name="value">The object to insert into cache.</param>
136
    /// <param name="absoluteExpiration">The fixed date and time at which the cache entry will expire.</param>
137
    /// <param name="slidingExpiration">A value that indicates whether a cache entry should be evicted if it has not been accessed in a given span of time.</param>
138
    /// <param name="cancellationToken">The cancellation instruction.</param>
139
    /// <exception cref="System.ArgumentException">'key' cannot be null or empty. - key</exception>
140
    /// <exception cref="System.ArgumentNullException">value</exception>
141
    public async Task SetAsync<T>(string key, T value, DateTimeOffset? absoluteExpiration = null, TimeSpan? slidingExpiration = null, CancellationToken cancellationToken = default)
142
    {
143
        if (string.IsNullOrEmpty(key))
2!
144
            throw new ArgumentException($"'{nameof(key)}' cannot be null or empty.", nameof(key));
×
145

146
        if (value is null)
2!
147
            throw new ArgumentNullException(nameof(value));
×
148

149
        // next set distributed cache
150
        var itemBuffer = await _distributedCacheSerializer
2✔
151
            .SerializeAsync(value, cancellationToken)
2✔
152
            .ConfigureAwait(false);
2✔
153

154
        var distributedOptions = new DistributedCacheEntryOptions
2✔
155
        {
2✔
156
            AbsoluteExpiration = absoluteExpiration,
2✔
157
            SlidingExpiration = slidingExpiration
2✔
158
        };
2✔
159

160
        await _distributedCache
2✔
161
            .SetAsync(key, itemBuffer, distributedOptions, cancellationToken)
2✔
162
            .ConfigureAwait(false);
2✔
163

164
        LogCacheInsert(_logger, key);
2✔
165
    }
2✔
166

167
    /// <summary>
168
    /// Removes the cache entry from the cache
169
    /// </summary>
170
    /// <param name="key">A unique identifier for the cache entry.</param>
171
    /// <exception cref="System.ArgumentException">'key' cannot be null or empty. - key</exception>
172
    public void Remove(string key)
173
    {
174
        if (string.IsNullOrEmpty(key))
×
175
            throw new ArgumentException($"'{nameof(key)}' cannot be null or empty.", nameof(key));
×
176

177
        LogCacheRemove(_logger, key);
×
178

179
        _distributedCache.Remove(key);
×
180
    }
×
181

182
    /// <summary>
183
    /// Removes the cache entry from the cache
184
    /// </summary>
185
    /// <param name="key">A unique identifier for the cache entry.</param>
186
    /// <param name="cancellationToken">The cancellation instruction.</param>
187
    /// <exception cref="System.ArgumentException">'key' cannot be null or empty. - key</exception>
188
    public async Task RemoveAsync(string key, CancellationToken cancellationToken = default)
189
    {
190
        if (string.IsNullOrEmpty(key))
×
191
            throw new ArgumentException($"'{nameof(key)}' cannot be null or empty.", nameof(key));
×
192

193
        LogCacheRemove(_logger, key);
×
194

195
        await _distributedCache.RemoveAsync(key, cancellationToken);
×
196
    }
×
197

198

199
    [LoggerMessage(0, LogLevel.Debug, "Cache Hit; Key: '{cacheKey}'")]
200
    static partial void LogCacheHit(ILogger logger, string cacheKey);
201

202
    [LoggerMessage(1, LogLevel.Debug, "Cache Miss; Key: '{cacheKey}'")]
203
    static partial void LogCacheMiss(ILogger logger, string cacheKey);
204

205
    [LoggerMessage(2, LogLevel.Debug, "Cache Insert; Key: '{cacheKey}'")]
206
    static partial void LogCacheInsert(ILogger logger, string cacheKey);
207

208
    [LoggerMessage(3, LogLevel.Debug, "Cache Remove; Key: '{cacheKey}'")]
209
    static partial void LogCacheRemove(ILogger logger, string cacheKey);
210
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc