EviCache 2.2.0
dotnet add package EviCache --version 2.2.0
NuGet\Install-Package EviCache -Version 2.2.0
<PackageReference Include="EviCache" Version="2.2.0" />
<PackageVersion Include="EviCache" Version="2.2.0" />
<PackageReference Include="EviCache" />
paket add EviCache --version 2.2.0
#r "nuget: EviCache, 2.2.0"
#:package EviCache@2.2.0
#addin nuget:?package=EviCache&version=2.2.0
#tool nuget:?package=EviCache&version=2.2.0
About
EviCache is a lightweight, thread-safe, in-memory caching library for .NET.
It supports multiple eviction policies and offers extended cache operations. Moreover, it provides metrics and inspection capabilities.
Table of Contents
Overview
Quick start
using EviCache;
using EviCache.Enums;
using EviCache.Options;
// Create a cache with LRU and capacity 100
var cache = new Cache<string, string>(new CacheOptions(
capacity: 100,
evictionPolicy: EvictionPolicy.LRU));
// Put & Get
cache.Put("user:1", "André");
var name = cache.Get("user:1"); // "André"
// GetOrAdd (adds on miss, returns existing on hit)
var color = cache.GetOrAdd("color", "blue");
// Per-item absolute expiration (e.g., 1 minute)
cache.Put("otp", "123456",
new CacheItemOptions {
Expiration = new ExpirationOptions.Absolute(TimeSpan.FromMinutes(1))
});
Async
// Same semantics, but async + cancellation support
await cache.PutAsync("k", "v", ct);
var value = await cache.GetAsync("k", ct);
var (found, v) = await cache.TryGetAsync("missing", ct);
Eviction policies
Choose via CacheOptions.EvictionPolicy:
- LRU: evicts least-recently-used.
- LFU: evicts least-frequently-used.
- FIFO: evicts oldest inserted.
- NoEviction: refuse to add when full; throws
CacheFullException.
When capacity is full, the cache evicts one candidate (if the policy allows). If no candidate can be evicted or policy is NoEviction, a CacheFullException is thrown with diagnostic data (capacity, attempted key, policy).
Expiration (TTL)
Set expiration globally (default for all items) or per item:
ExpirationOptions.Absolute(TimeSpan ttl): expires atnow + ttl.ExpirationOptions.Sliding(TimeSpan ttl): expires if not accessed withinttl.ExpirationOptions.None: no expiration.
Examples:
// Global default expiration: absolute 10 minutes
var cache = new Cache<string, byte[]>(new CacheOptions(
100, EvictionPolicy.LFU,
new ExpirationOptions.Absolute(TimeSpan.FromMinutes(10))));
// Per-item sliding expiration: 5 minutes
cache.Put("session:12", session,
new CacheItemOptions {
Expiration = new ExpirationOptions.Sliding(TimeSpan.FromMinutes(5))
});
Expired items are purged lazily on access and during capacity checks; they won’t appear in
GetKeys()/GetSnapshot().
API overview
- Retrieval
Get(key)→ value (throws if missing).TryGet(key, out value)/TryGetAsync→ no throw.ContainsKey(key)/ContainsKeyAsync→ does not affect hit/miss counters.
- Mutation
Put(key, value)/Put(key, value, options)→ insert or update.AddOrUpdate(key, value)→ inserts on miss; returns the provided value.GetOrAdd(key, value)→ returns existing value on hit; otherwise, inserts and returns the provided value.Remove(key)→ bool;Clear()→ clears all.
- Inspection
GetKeys()→ImmutableList<TKey>of non-expired keys (order depends on policy).GetSnapshot()→ImmutableList<KeyValuePair<TKey,TValue>>of non-expired entries.
- Metadata
GetMetadata(key)/TryGetMetadata(key, out meta)→ last access/update, access count, expiration, etc.
- Metrics
Capacity,Count(purges expired first),Hits,Misses,Evictions.
Hits & Misses
- Successful
Get/TryGet/GetOrAdd(hit path) increments Hits and updates access metadata + policy structures. - Miss paths increment Misses.
ContainsKeyis intentionally “cold”: it checks existence without touching metrics or access ordering.
Thread-safety
All public operations are protected by an internal SemaphoreSlim, ensuring a single writer/reader critical section. Both sync and async APIs are safe to call concurrently.
Disposal semantics
- If a cached value implements
IDisposable/IAsyncDisposable, it is disposed when the entry is removed, evicted, updated (when replacing a different instance), or duringClear(). Clear()gathers disposables and disposes them in the background (respecting the provided cancellation token inClearAsync). Errors during disposal are logged.
Logging
Pass an ILogger to the constructor or rely on the default NullLogger. Notable events:
- Initialization (capacity, policy) at
Information. - Evictions at
Debug. - Errors during eviction selection or background disposal at
Error.
Exceptions
KeyNotFoundException: Get on a non-existing/expired key.CacheFullException: when full and:- policy is
NoEviction, or - an eviction candidate couldn’t be selected/removed.
- policy is
CacheFullException includes Capacity, the attempted key (if available), and EvictionPolicy for diagnostics.
Performance notes
- Keys are tracked per policy for fast candidate selection;
GetKeys()returns a filtered, immutable snapshot without expired entries. Counttriggers a purge of expired items before returning the size.- Avoid calling
ContainsKeyas a pre-check beforeGet— do a singleTryGetto minimize lock acquisitions.
<a id="feedback"></a>
Feedback & Contributing
EviCache is released as open source under the MIT license. Bug reports and contributions are welcome at the GitHub repository.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. 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 is compatible. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.