Open.Caching.Runtime
3.1.1
dotnet add package Open.Caching.Runtime --version 3.1.1
NuGet\Install-Package Open.Caching.Runtime -Version 3.1.1
<PackageReference Include="Open.Caching.Runtime" Version="3.1.1" />
paket add Open.Caching.Runtime --version 3.1.1
#r "nuget: Open.Caching.Runtime, 3.1.1"
// Install Open.Caching.Runtime as a Cake Addin #addin nuget:?package=Open.Caching.Runtime&version=3.1.1 // Install Open.Caching.Runtime as a Cake Tool #tool nuget:?package=Open.Caching.Runtime&version=3.1.1
Open.Caching
Useful set of DI/IoC agnostic interfaces, utilities and extensions for simplifying cache usage.
Implementation
With the following libraries, you can build other libraries that sever their dependency from any cache and allow you to inject whichever you want.
Core Interfaces & Extensions
Open.Caching
https://www.nuget.org/packages/Open.Caching
Core package for interfaces and base classes.
Library/Vendor Specific Implementations
Open.Caching.Memory
https://www.nuget.org/packages/Open.Caching.Memory
Contains MemoryCacheAdapter
for use with any IMemoryCache
.
Open.Caching.Runtime
https://www.nuget.org/packages/Open.Caching.Runtime
Contains ObjectCacheAdapter
for use with any System.Runtime.Caching.ObjectCache
.
Open.Caching.Web
https://www.nuget.org/packages/Open.Caching.Web
Contains WebCacheAdapter
for use with any System.Web.Caching.Cache
.
Useful when attempting to transition code away from legacy ASP.NET.
Notable Similarities & Differences
The above adapters all accept strings as keys,
but only MemoryCacheAdapter
will accept any type of key as IMemoryCache
uses object
s as keys. If your dependency injection configuration uses ICacheAdapter<string>
as its cache interface then any of the implementations can be used. So if you are transitioning from a legacy ASP.NET environment, switching to MemoryCacheAdapter<string>
will make things easy.
Every cache implementation listed handles absolute and sliding expiration.
Because IMemoryCache
allows for null
values to be inserted,
the other implementations use a placeholder NullValue
to indicate null
and retain parity for all implementations.
Not Yet Supported
Some of the reasons for not supporting certain features should be obvious.
The intention of these utilities is to cover the 95%+ use case.
Setting expiration is very common, but setting priority is not so common.
- At this time, 'priority' is not supported as each cache has a slightly different implementation.
- Eviction call backs, cache item or file system watchers.
Interfaces, Classes, & Structs
ICacheAdapter<TKey>
Modeled after Microsoft.Extensions.Caching.Memory.IMemoryCache
, this interface facilitates cache access for all adapters and extensions.
namespace Open.Caching;
public interface ICacheAdapter<TKey>
{
bool TryGetValue<TValue>(
TKey key,
out TValue item,
bool throwIfUnexpectedType = false);
void Set<TValue>(TKey key, TValue item);
void Remove(TKey key);
}
It does not offer a mechanism for a cache policy as that is provided by CacheAdapterBase<TKey, TCache>
.
ExpirationPolicy
This read only struct combines both .Absolute
and .Sliding
expirations into TimeSpan
values.
.Absolute
is a TimeSpan
as it is almost always the case that expiration happens relative from when the cache entry was inserted.
DateTimeOffset AbsoluteRelativeToNow
is derived from the value of .Absolute
and the DateTimeOffset.Now
ICachePolicyProvider<TKey, TPolicy>
This interface allows for returning a specific ICacheAdapter<TKey
that will default to that policy.
CacheAdapterBase<TKey, TCache>
Every adapter derives from this base class and implements the ICachePolicyProvider<TKey, ExpirationPolicy>
interface. Allowing for simple or policy driven cache access.
CacheItem<TKey, TValue>
The intention of this and the following classes is to simplify access to a cached resource.
Much like a Lazy<T>
, or any other container class, you can affix, or pass around these classes without the consumer having to know what the key is.
public class MyClass {
// Injected ICacheAdapter<string>.
public MyClass(ICacheAdapter<string> cache)
{
// The key is defined in only one place.
_value = cache
.CreateItem(
key: "a cache key",
defaultValue: "[not set]");
}
readonly CacheItem<string, string> _value;
public string Value {
get => _value; // Implicit
set => _value.Value = value;
}
}
LazyCacheItem<TKey, TValue>
The important idea here is to allow for the insertion of a Lazy<T>
so that any subsequent requests to that resource either wait for it to complete, or receive the already resolved value.
The underlying .GetOrCreateLazy<T>
extension properly evicts the Lazy<T>
if the Value
property throws an exception.
public class MyClass {
// Injected ICacheAdapter<string>.
public MyClass(ICacheAdapter<string> cache)
{
// The key is defined in only one place.
_value = cache
.CreateLazyItem(
key: "a cache key",
()=>{
/* long running process. */
});
}
public string Value => _value; // Implicit
}
AsyncLazyCacheItem<TKey, TValue>
This class implements IAsyncCacheItem<TValue>
and therefore is awaitable.
Similar to the above, the underlying .GetOrCreateLazyAsync
method uses a Lazy<Task<T>>>
to initialize the method and asynchronously produce a result. Any exceptions thrown by the the Task<T>
or its factory method will evict the entry from the cache.
public class MyClass {
// Injected ICacheAdapter<string>.
public MyClass(ICacheAdapter<string> cache)
{
// The key is defined in only one place.
_value = cache
.CreateAsyncLazyItem(
key: "a cache key",
async ()=>{
/* long running async process. */
});
}
public Task<string> Value => _value; // Implicit
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Open.Caching (>= 3.1.1)
- System.Runtime.Caching (>= 7.0.0)
-
.NETStandard 2.1
- Open.Caching (>= 3.1.1)
- System.Runtime.Caching (>= 7.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.