diff --git a/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCache.cs b/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCache.cs
deleted file mode 100644
index e598921a..00000000
--- a/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCache.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-namespace DotNetToolkit.Repository.Caching.InMemory
-{
- using Configuration.Caching;
- using JetBrains.Annotations;
- using Microsoft.Extensions.Caching.Memory;
- using System;
- using Utility;
-
- ///
- /// An implementation of .
- ///
- public class InMemoryCache : ICache
- {
- #region Fields
-
- private readonly IMemoryCache _cache;
-
- #endregion
-
- #region Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The underlying caching storage.
- public InMemoryCache([NotNull] IMemoryCache cache)
- {
- _cache = Guard.NotNull(cache, nameof(cache));
- }
-
- #endregion
-
- #region Private Methods
-
- private void Set(string key, T value, CacheItemPriority priority, TimeSpan? expiry, Action cacheRemovedCallback = null)
- {
- Guard.NotEmpty(key, nameof(key));
-
- var policy = new MemoryCacheEntryOptions();
-
- if (cacheRemovedCallback != null)
- {
- policy.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration
- {
- EvictionCallback = (o, val, reason, state) =>
- {
- cacheRemovedCallback(reason.ToString());
- }
- });
- }
-
- if (expiry.HasValue && expiry.Value != TimeSpan.Zero)
- policy.AbsoluteExpiration = DateTimeOffset.Now.Add(expiry.Value);
-
- if (expiry.HasValue && expiry.Value == TimeSpan.Zero && priority != CacheItemPriority.NeverRemove)
- policy.Priority = CacheItemPriority.NeverRemove;
- else
- policy.Priority = priority;
-
- _cache.Set(key, value, policy);
- }
-
- #endregion
-
- #region Implementation of ICache
-
- ///
- /// Create or overwrite an entry in the cache.
- ///
- /// The type of the cache value.
- /// An object identifying the entry.
- /// The value to cache.
- /// The cache expiration time.
- /// A callback function for a value is removed from the cache.
- public void Set([NotNull] string key, T value, TimeSpan? expiry, Action cacheRemovedCallback = null)
- {
- Set(key, value, CacheItemPriority.Normal, expiry, cacheRemovedCallback);
- }
-
- ///
- /// Removes the object associated with the given key.
- ///
- /// An object identifying the entry.
- public void Remove([NotNull] string key)
- {
- _cache.Remove(Guard.NotEmpty(key, nameof(key)));
- }
-
- ///
- /// Gets the item associated with this key if present.
- ///
- /// The type of the cache value.
- /// An object identifying the requested entry.
- /// The object found in the cache.
- /// ctrue if the an object was found with the specified key; otherwise, false.
- public bool TryGetValue([NotNull] string key, out T value)
- {
- return _cache.TryGetValue(Guard.NotEmpty(key, nameof(key)), out value);
- }
-
- ///
- /// Increments the number stored at key by one
- ///
- /// The key.
- /// The default value.
- /// The increment value.
- /// The value of key after the increment.
- public int Increment([NotNull] string key, int defaultValue, int incrementValue)
- {
- Guard.NotEmpty(key, nameof(key));
-
- if (!TryGetValue(key, out var current))
- current = defaultValue;
-
- var value = current + incrementValue;
-
- Set(key, value, CacheItemPriority.NeverRemove, expiry: null);
-
- return value;
- }
-
- #endregion
-
- #region Implementation of IDisposable
-
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- public void Dispose()
- {
- _cache.Dispose();
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCacheOptions.cs b/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCacheOptions.cs
new file mode 100644
index 00000000..ebbb260c
--- /dev/null
+++ b/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCacheOptions.cs
@@ -0,0 +1,52 @@
+namespace DotNetToolkit.Repository.Caching.InMemory
+{
+ using DotNetToolkit.Repository.Utility;
+ using JetBrains.Annotations;
+ using Microsoft.Extensions.Internal;
+ using System;
+
+ ///
+ /// The options to be used by the in-memory caching provider.
+ ///
+ public class InMemoryCacheOptions
+ {
+ internal ISystemClock Clock { get; set; }
+ internal TimeSpan? ExpirationScanFrequency { get; set; }
+ internal TimeSpan? Expiry { get; set; }
+
+ internal InMemoryCacheOptions() { }
+
+ ///
+ /// Adds the giving system clock vaue to the options.
+ ///
+ /// The system clock to be added.
+ public InMemoryCacheOptions WithClock([NotNull] ISystemClock clock)
+ {
+ Clock = Guard.NotNull(clock, nameof(clock));
+
+ return this;
+ }
+
+ ///
+ /// Adds the giving system clock vaue to the options.
+ ///
+ /// The minimum length of time between successive scans for expired items to be added.
+ public InMemoryCacheOptions WithExpirationScanFrequency([NotNull] TimeSpan expirationScanFrequency)
+ {
+ ExpirationScanFrequency = Guard.NotNull(expirationScanFrequency, nameof(expirationScanFrequency));
+
+ return this;
+ }
+
+ ///
+ /// Adds the giving caching expiration time to the options.
+ ///
+ /// The caching expiration time to be added.
+ public InMemoryCacheOptions WithExpiry([NotNull] TimeSpan expiry)
+ {
+ Expiry = Guard.NotNull(expiry, nameof(expiry));
+
+ return this;
+ }
+ }
+}
diff --git a/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCacheProvider.cs b/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCacheProvider.cs
index 022154e4..40d200c0 100644
--- a/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCacheProvider.cs
+++ b/src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCacheProvider.cs
@@ -3,54 +3,29 @@
using Configuration.Caching;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Memory;
+ using Microsoft.Extensions.Internal;
using System;
using Utility;
- ///
- /// An implementation of .
- ///
- public class InMemoryCacheProvider : CacheProviderBase
+ internal class InMemoryCacheProvider : ICacheProvider
{
+ #region Properties
+
+ public IMemoryCache Cache { get; }
+ public TimeSpan? Expiry { get; set; }
+
+ #endregion
+
#region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- public InMemoryCacheProvider() : this((TimeSpan?)null) { }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The caching expiration time.
- public InMemoryCacheProvider([CanBeNull] TimeSpan? expiry) : this(new MemoryCache(new MemoryCacheOptions()), expiry) { }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The configuration options action.
- public InMemoryCacheProvider([NotNull] Action optionsAction) : this(optionsAction, (TimeSpan?)null) { }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The configuration options action.
- /// The caching expiration time.
- public InMemoryCacheProvider([NotNull] Action optionsAction, [CanBeNull] TimeSpan? expiry) : this(new MemoryCache(GetConfigurationOptions(optionsAction)), expiry) { }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The underlying caching storage.
- public InMemoryCacheProvider([NotNull] IMemoryCache cache) : this(cache, (TimeSpan?)null) { }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The underlying caching storage.
- /// The caching expiration time.
- public InMemoryCacheProvider([NotNull] IMemoryCache cache, [CanBeNull] TimeSpan? expiry)
+ public InMemoryCacheProvider() : this(null, null, null) { }
+
+ public InMemoryCacheProvider(ISystemClock clock, TimeSpan? expirationScanFrequency, TimeSpan? expiry)
+ : this (GetMemoryCacheOptions(clock, expirationScanFrequency), expiry) { }
+
+ private InMemoryCacheProvider(MemoryCacheOptions options, TimeSpan? expiry)
{
- Cache = new InMemoryCache(Guard.NotNull(cache, nameof(cache)));
+ Cache = new MemoryCache(Guard.NotNull(options, nameof(options)));
Expiry = expiry;
}
@@ -58,17 +33,81 @@ public InMemoryCacheProvider([NotNull] IMemoryCache cache, [CanBeNull] TimeSpan?
#region Private Methods
- private static MemoryCacheOptions GetConfigurationOptions(Action optionsAction)
+ private static MemoryCacheOptions GetMemoryCacheOptions(ISystemClock clock, TimeSpan? expirationScanFrequency)
{
- Guard.NotNull(optionsAction, nameof(optionsAction));
-
var options = new MemoryCacheOptions();
- optionsAction(options);
+ options.Clock = clock;
+
+ if (expirationScanFrequency.HasValue)
+ {
+ options.ExpirationScanFrequency = expirationScanFrequency.Value;
+ }
return options;
}
+ private void Set(string key, T value, CacheItemPriority priority, TimeSpan? expiry, Action cacheRemovedCallback = null)
+ {
+ Guard.NotEmpty(key, nameof(key));
+
+ var policy = new MemoryCacheEntryOptions();
+
+ if (cacheRemovedCallback != null)
+ {
+ policy.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration
+ {
+ EvictionCallback = (o, val, reason, state) =>
+ {
+ cacheRemovedCallback(reason.ToString());
+ }
+ });
+ }
+
+ if (expiry.HasValue && expiry.Value != TimeSpan.Zero)
+ policy.AbsoluteExpiration = DateTimeOffset.Now.Add(expiry.Value);
+
+ if (expiry.HasValue && expiry.Value == TimeSpan.Zero && priority != CacheItemPriority.NeverRemove)
+ policy.Priority = CacheItemPriority.NeverRemove;
+ else
+ policy.Priority = priority;
+
+ Cache.Set(key, value, policy);
+ }
+
+ #endregion
+
+ #region Implementation of ICacheProvider
+
+ public void Set([NotNull] string key, T value, TimeSpan? expiry = null, Action cacheRemovedCallback = null)
+ {
+ Set(key, value, CacheItemPriority.Normal, expiry ?? Expiry, cacheRemovedCallback);
+ }
+
+ public void Remove([NotNull] string key)
+ {
+ Cache.Remove(Guard.NotEmpty(key, nameof(key)));
+ }
+
+ public bool TryGetValue([NotNull] string key, out T value)
+ {
+ return Cache.TryGetValue(Guard.NotEmpty(key, nameof(key)), out value);
+ }
+
+ public int Increment([NotNull] string key, int defaultValue, int incrementValue)
+ {
+ Guard.NotEmpty(key, nameof(key));
+
+ if (!TryGetValue(key, out var current))
+ current = defaultValue;
+
+ var value = current + incrementValue;
+
+ Set(key, value, CacheItemPriority.NeverRemove, expiry: null);
+
+ return value;
+ }
+
#endregion
}
}