ZiggyCreatures.FusionCache 0.10.0-preview1

Prefix Reserved
This is a prerelease version of ZiggyCreatures.FusionCache.
There is a newer version of this package available.
See the version list below for details.
dotnet add package ZiggyCreatures.FusionCache --version 0.10.0-preview1                
NuGet\Install-Package ZiggyCreatures.FusionCache -Version 0.10.0-preview1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ZiggyCreatures.FusionCache" Version="0.10.0-preview1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ZiggyCreatures.FusionCache --version 0.10.0-preview1                
#r "nuget: ZiggyCreatures.FusionCache, 0.10.0-preview1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ZiggyCreatures.FusionCache as a Cake Addin
#addin nuget:?package=ZiggyCreatures.FusionCache&version=0.10.0-preview1&prerelease

// Install ZiggyCreatures.FusionCache as a Cake Tool
#tool nuget:?package=ZiggyCreatures.FusionCache&version=0.10.0-preview1&prerelease                

FusionCache

FusionCache logo

FusionCache is an easy to use, high performance and robust cache with an optional distributed 2nd layer and some advanced features.

It was born after years of dealing with all sorts of different types of caches: memory caching, distributed caching, http caching, CDNs, browser cache, offline cache, you name it. So I've tried to put together these experiences and came up with FusionCache.

It uses a memory cache (any impl of the standard IMemoryCache interface) as the primary backing store and optionally a distributed, 2nd level cache (any impl of the standard IDistributedCache interface) as a secondary backing store for better resilience and higher performance, for example in a multi-node scenario or to avoid the typical effects of a cold start (initial empty cache, maybe after a restart).

Optionally, it can also use a backplane: in a multi-node scenario this will send notifications to the other nodes to keep each node's memory cache perfectly synchronized, without any additional work.

FusionCache also includes some advanced features like a fail-safe mechanism, cache stampede prevention, fine grained soft/hard timeouts with background factory completion, customizable extensive logging and more (see below).

FusionCache diagram

🏆 Award

On August 2021, FusionCache received the Google Open Source Peer Bonus Award. Here is the official blogpost.

✔ Features

These are the key features of FusionCache:

  • 🚀 Cache Stampede prevention: using the optimized GetOrSet[Async] method prevents multiple concurrent factory calls per key, with a guarantee that only 1 factory will be called at the same time for the same key (this avoids overloading the data source when no data is in the cache or when a cache entry expires)
  • 🔀 Optional 2nd level: FusionCache can transparently handle an optional 2nd level cache: anything that implements the standard IDistributedCache interface is supported (eg: Redis, MongoDB, SqlServer, etc)
  • 📢 Backplane: when using a distributed cache as a 2nd layer in a multi-node scenario, you can also enable a backplane to immediately notify the other nodes about changes in the cache, to keep everything synchronized without having to do anything
  • 💣 Fail-Safe: enabling the fail-safe mechanism prevents throwing an exception when a factory or a distributed cache call would fail, by reusing an expired entry as a temporary fallback, all transparently and with no additional code required
  • ⏱ Soft/Hard timeouts: advanced timeouts management prevents waiting for too long when calling a factory or the distributed cache, to avoid hanging your application. It is possible to specify both soft and hard timeouts, and thanks to automatic background completion no data will be wasted
  • 🧙‍♂️ Adaptive Caching: there are times when you don't know upfront what the cache duration for a piece of data should be, maybe because it depends on the object being cached itself. Adaptive caching solves this elegantly
  • ⚡ High performance: FusionCache is optimized to minimize CPU usage and memory allocations to get better performance and lower the cost of your infrastructure all while obtaining a more stable, error resilient application
  • 💫 Natively sync/async: full native support for both the synchronous and asynchronous programming model, with sync/async methods working together harmoniously
  • 📞 Events: there's a comprehensive set of events to subscribe to regarding core events inside of a FusioCache instance, both at a high level and at lower levels (memory/distributed layers)
  • 🧩 Plugins: thanks to a plugin subsystem it is possible to extend FusionCache with additional behaviour, like adding support for metrics, statistics, etc...
  • 📃 Extensive logging: comprehensive, structured, detailed and customizable logging via the standard ILogger interface (you can use Serilog, NLog, etc)

⭐ Quick Start

FusionCache can be installed via the nuget UI (search for the ZiggyCreatures.FusionCache package) or via the nuget package manager console:

PM> Install-Package ZiggyCreatures.FusionCache

As an example, imagine having a method that retrieves a product from your database:

Product GetProductFromDb(int id) {
	// YOUR DATABASE CALL HERE
}

💡 This is using the sync programming model, but it would be equally valid with the newer async one for even better performance.

To start using FusionCache the first thing is create a cache instance:

var cache = new FusionCache(new FusionCacheOptions());

If instead you are using DI (Dependency Injection) use this:

services.AddFusionCache();

We can also specify some global options, like a default FusionCacheEntryOptions object to serve as a default for each call we'll make, with a duration of 2 minutes and a Low priority:

var cache = new FusionCache(new FusionCacheOptions() {
	DefaultEntryOptions = new FusionCacheEntryOptions {
		Duration = TimeSpan.FromMinutes(2),
		Priority = CacheItemPriority.Low
	}
});

Or, using DI, like this:

services.AddFusionCache(options => {
	options.DefaultEntryOptions = new FusionCacheEntryOptions {
		Duration = TimeSpan.FromMinutes(2),
		Priority = CacheItemPriority.Low
	}
});

Now, to get the product from the cache and, if not there, get it from the database in an optimized way and cache it for 30 sec simply do this:

var id = 42;

cache.GetOrSet<Product>(
	$"product:{id}",
	_ => GetProductFromDb(id),
	TimeSpan.FromSeconds(30)
);

That's it 🎉

📖 Documentation

A complete documentation, including examples and common use cases, is available at the official repo page on GitHub.

🧰 Supported Platforms

FusionCache targets .NET Standard 2.0 so any compatible .NET implementation is fine: this means .NET Framework (the old one), .NET Core 2+ and .NET 5/6+ (the new ones), Mono 5.4+ and more (see here for a complete rundown).

NOTE: if you are running on .NET Framework 4.6.1 and want to use .NET Standard packages Microsoft suggests to upgrade to .NET Framework 4.7.2 or higher (see the .NET Standard Documentation) to avoid some known dependency issues.

Product 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 was computed. 
.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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (27)

Showing the top 5 NuGet packages that depend on ZiggyCreatures.FusionCache:

Package Downloads
ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis

FusionCache backplane for Redis based on the StackExchange.Redis library

ZiggyCreatures.FusionCache.Serialization.NewtonsoftJson

FusionCache serializer based on Newtonsoft Json.NET

ZiggyCreatures.FusionCache.Serialization.SystemTextJson

FusionCache serializer based on System.Text.Json

Auth0Net.DependencyInjection

Dependency Injection, HttpClientFactory & ASP.NET Core extensions for Auth0.NET

ZiggyCreatures.FusionCache.OpenTelemetry

Add native OpenTelemetry support to FusionCache.

GitHub repositories (8)

Showing the top 5 popular GitHub repositories that depend on ZiggyCreatures.FusionCache:

Repository Stars
Azure/data-api-builder
Data API builder provides modern REST and GraphQL endpoints to your Azure Databases and on-prem stores.
neozhu/CleanArchitectureWithBlazorServer
This is a repository for creating a Blazor Server dashboard application following the principles of Clean Architecture
TurnerSoftware/CacheTower
An efficient multi-layered caching system for .NET
ikyriak/IdempotentAPI
A .NET library that handles the HTTP write operations (POST and PATCH) that can affect only once for the given request data and idempotency-key by using an ASP.NET Core attribute (filter).
JasonBock/Rocks
A mocking library based on the Compiler APIs (Roslyn + Mocks)
Version Downloads Last updated
2.0.0-preview-3 1,233 12/9/2024
2.0.0-preview-2 1,567 11/14/2024
2.0.0-preview-1 962 11/10/2024
1.4.1 164,534 10/27/2024
1.4.0 290,013 9/15/2024
1.3.0 327,112 8/4/2024
1.2.0 362,430 6/2/2024
1.2.0-preview1 892 5/19/2024
1.1.0 164,389 4/24/2024
1.0.0 259,721 2/29/2024
1.0.0-preview2 4,448 2/23/2024
1.0.0-preview1 1,266 2/11/2024
0.26.0 137,517 2/11/2024
0.25.0 6,944 2/4/2024 0.25.0 is deprecated.
0.25.0-preview1 1,376 1/14/2024
0.24.0 317,521 11/12/2023
0.24.0-preview1 1,924 9/3/2023
0.23.0 365,248 8/1/2023
0.22.0 60,460 7/9/2023
0.21.0 871,002 5/28/2023
0.21.0-preview2 1,810 5/21/2023
0.21.0-preview1 1,792 5/1/2023
0.20.0 156,737 4/8/2023
0.20.0-preview2 1,663 3/29/2023
0.20.0-preview1 1,968 3/3/2023
0.19.0 168,665 2/12/2023
0.18.0 112,183 12/18/2022
0.17.0 18,876 12/4/2022
0.16.0 20,476 11/12/2022
0.15.0 225,372 10/26/2022
0.14.0 10,842 10/18/2022
0.13.0 109,327 8/14/2022
0.12.0 8,642 7/19/2022
0.11.1 2,976 7/15/2022
0.11.0 3,013 7/12/2022
0.10.0 160,923 5/1/2022
0.10.0-preview1 1,662 4/23/2022
0.9.0 69,483 2/17/2022
0.1.10-beta3 3,378 2/14/2022
0.1.10-beta2 1,684 2/11/2022
0.1.10-beta1 1,629 2/9/2022
0.1.10-alpha2 1,705 1/30/2022
0.1.10-alpha1 1,518 1/27/2022
0.1.9 52,382 11/23/2021
0.1.8 7,328 11/23/2021
0.1.7 19,941 10/16/2021
0.1.6 36,581 8/1/2021
0.1.5 5,079 6/29/2021
0.1.4 4,656 6/5/2021
0.1.3 4,238 4/3/2021
0.1.2 14,810 2/26/2021
0.1.1 2,794 1/19/2021
0.1.0 3,020 12/31/2020

- added support for adaptive caching
- added an optimization to use the FactorySoftTimeout as a LockTimeout in case a custom one has not been specified + fail-safe is enabled + there's a fallback entry, so that in certain situations there can be a perf boost
- added IFusionCache.HasDistributedCache prop to know if there is a distributed cache configured
- added a warning log in case there's a backplane configured without a distributed cache and DefaultEntryOptions.EnableBackplaneNotifications == true , since this can be dangerous
- better nullability decoration