### Setup OpenTelemetry Traces and Metrics (With DI) Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/OpenTelemetry.md Configure OpenTelemetry traces and metrics instrumentation for FusionCache using dependency injection. This example also uses console exporters. ```csharp services.AddOpenTelemetry() // SETUP TRACES .WithTracing(tracing => tracing .AddFusionCacheInstrumentation() .AddConsoleExporter() ) // SETUP METRICS .WithMetrics(metrics => metrics .AddFusionCacheInstrumentation() .AddConsoleExporter() ); ``` -------------------------------- ### Setup OpenTelemetry Traces and Metrics (No DI) Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/OpenTelemetry.md Configure OpenTelemetry traces and metrics instrumentation for FusionCache without using dependency injection. This example uses console exporters for demonstration. ```csharp // SETUP TRACES using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddFusionCacheInstrumentation() .AddConsoleExporter() .Build(); // SETUP METRICS using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddFusionCacheInstrumentation() .AddConsoleExporter() .Build(); ``` -------------------------------- ### Complete FusionCache Setup with Redis Components Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheStampede.md A comprehensive example of setting up FusionCache with Redis for serialization, distributed cache, backplane, and distributed locker. This ensures all components work together for robust caching. ```csharp services.AddFusionCache() // SERIALIZER .WithSerializer( new FusionCacheSystemTextJsonSerializer() ) // DISTRIBUTED CACHE .WithDistributedCache( new RedisCache(new RedisCacheOptions { Configuration = "localhost:6379", }) ) // BACKPLANE .WithBackplane( new RedisBackplane(new RedisBackplaneOptions { Configuration = "localhost:6379", }) ) // DISTRIBUTED LOCKER <-- HERE IT IS! .WithDistributedLocker( new RedisDistributedLocker(new RedisDistributedLockerOptions { Configuration = "localhost:6379", }) ); ``` -------------------------------- ### Install Redis and System.Text.Json Packages Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/StepByStep.md Install the necessary NuGet packages for Redis distributed caching and System.Text.Json serialization. ```powershell PM> Install-Package Microsoft.Extensions.Caching.StackExchangeRedis PM> Install-Package ZiggyCreatures.FusionCache.Serialization.SystemTextJson ``` -------------------------------- ### Install Redis Distributed Locker Package Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/StepByStep.md Install the ZiggyCreatures.FusionCache.Locking.Distributed.Redis NuGet package using PowerShell. ```powershell PM> Install-Package ZiggyCreatures.FusionCache.Locking.Distributed.Redis ``` -------------------------------- ### Install FusionCache NuGet Package Source: https://github.com/ziggycreatures/fusioncache/blob/main/README.md Install the ZiggyCreatures.FusionCache Nuget package using PowerShell. ```powershell PM> Install-Package ZiggyCreatures.FusionCache ``` -------------------------------- ### FusionCache Auto-Clone Setup and Usage Example Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/AutoClone.md Demonstrates how to set up FusionCache with a serializer and then use the Auto-Clone feature to retrieve and modify cached objects. It highlights the difference between getting a cloned instance (using SetAutoClone(true)) and a direct reference. ```csharp // SETUP var cache = new FusionCache(new FusionCacheOptions()); cache.SetupSerializer(new FusionCacheSystemTextJsonSerializer()); // USAGE cache.Set("foo", new Person { Name = "John" }); // RETURNS A CLONE OF THE CACHED INSTANCE var person1 = cache.GetOrDefault("foo", options => options.SetAutoClone(true)); Console.WriteLine($"person1: {person1.Name}"); Console.WriteLine(); // RETURNS A CLONE OF THE CACHED INSTANCE: CHANGES APPLIED ONLY THE CLONE, CACHED INSTANCE REMAINS UNCHANGED var person2 = cache.GetOrDefault("foo", options => options.SetAutoClone(true)); person2.Name = "Jane"; Console.WriteLine($"person1: {person1.Name}"); Console.WriteLine($"person2: {person2.Name}"); Console.WriteLine(); // RETURNS DIRECT REFERENCE TO THE CACHED INSTANCE: CHANGES APPLIED TO THE CACHED INSTANCE ITSELF var person3 = cache.GetOrDefault("foo"); person3.Name = "Jim"; Console.WriteLine($"person1: {person1.Name}"); Console.WriteLine($"person2: {person2.Name}"); Console.WriteLine($"person3: {person3.Name}"); Console.WriteLine(); // RETURNS DIRECT REFERENCE TO THE CACHED INSTANCE: THE INSTANCE IS THE SAME AS BEFORE // CHANGES APPLIED TO BOTH person3 AND person4 AS THEY POINT TO THE SAME CACHED INSTANCE var person4 = cache.GetOrDefault("foo"); person4.Name = "Joe"; Console.WriteLine($"person1: {person1.Name}"); Console.WriteLine($"person2: {person2.Name}"); Console.WriteLine($"person3: {person3.Name}"); Console.WriteLine($"person4: {person4.Name}"); ``` -------------------------------- ### Create FusionCache Instance (Manual) Source: https://github.com/ziggycreatures/fusioncache/blob/main/README.md Instantiate FusionCache with default options. This is for manual setup without dependency injection. ```csharp var cache = new FusionCache(new FusionCacheOptions()); ``` -------------------------------- ### Install OpenTelemetry Package Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/OpenTelemetry.md Install the FusionCache OpenTelemetry integration package using the Package Manager Console. ```PowerShell PM> Install-Package ZiggyCreatures.FusionCache.OpenTelemetry ``` -------------------------------- ### Install FusionCache Packages Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheLevels.md Installs the necessary FusionCache packages for Redis and Newtonsoft Json.NET integration. ```PowerShell PM> Install-Package ZiggyCreatures.FusionCache PM> Install-Package ZiggyCreatures.FusionCache.Serialization.NewtonsoftJson PM> Install-Package Microsoft.Extensions.Caching.StackExchangeRedis ``` -------------------------------- ### Basic GetOrSet with Duration Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Timeouts.md This is a basic example of getting or setting a cache entry with a specified duration. It does not include any timeout configurations. ```csharp product = cache.GetOrSet( "product:123", _ => GetProductFromDb(123), options => options .SetDuration(TimeSpan.FromMinutes(2)) ); ``` -------------------------------- ### Install StackExchange.Redis Backplane Package Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/StepByStep.md Install the NuGet package for integrating Redis as a backplane with FusionCache. This is a prerequisite for using Redis-based backplane functionality. ```powershell PM> Install-Package ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis ``` -------------------------------- ### TryGet Example Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CoreMethods.md Illustrates how to use TryGet to safely check for a value's existence and retrieve it, avoiding ambiguity with default values. Use when it's crucial to distinguish between a missing entry and a cached default value. ```csharp var maybeFoo = cache.TryGet("foo"); if (maybeFoo.HasValue) { // SUCCESS: THE VALUE WAS THERE // GET THE VALUE var result = maybeFoo.Value; } else { // FAIL: THE VALUE WAS NOT THERE } // DOING THIS WITHOUT CHECKING MAY THROW AN InvalidOperationException IF THE VALUE WAS NOT THERE var result = maybeFoo.Value; // THIS WILL GET THE VALUE, IF IT WAS THERE, OR THE SPECIFIED DEFAULT VALUE OTHERWISE var result = maybeFoo.GetValueOrDefault(42); // THIS WILL GET THE VALUE, IF IT WAS THERE, OR THE DEFAULT VALUE OF int OTHERWISE var result = maybeFoo.GetValueOrDefault(); // YOU CAN ALSO USE AN IMPLICIT CONVERSION BETWEEN MaybeValue AND T // BUT REMEMBER, IF NO VALUE IS THERE IT THROWS AN InvalidOperationException int result = maybeFoo; ``` -------------------------------- ### Define Product Loading Method Source: https://github.com/ziggycreatures/fusioncache/blob/main/README.md Example of a synchronous method to retrieve a product from the database. This serves as the factory method for caching. ```csharp Product GetProductFromDb(int id) { // DATABASE CALL HERE } ``` -------------------------------- ### Register and Use a Backplane via DI Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/DependencyInjection.md This example demonstrates registering a Redis backplane in the DI container and then instructing FusionCache to use the registered backplane. ```csharp services.AddFusionCacheStackExchangeRedisBackplane(opt => { opt.Configuration = "CONNECTION_STRING_HERE"; }); services.AddFusionCache() .WithRegisteredBackplane() ; ``` -------------------------------- ### Manual FusionCache Setup with Redis Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheLevels.md Manually instantiates and configures FusionCache with a Redis distributed cache and Newtonsoft Json.NET serializer. ```csharp // INSTANTIATE A REDIS DISTRIBUTED CACHE var redis = new RedisCache(new RedisCacheOptions() { Configuration = "CONNECTION STRING" }); // INSTANTIATE THE FUSION CACHE SERIALIZER var serializer = new FusionCacheNewtonsoftJsonSerializer(); // INSTANTIATE FUSION CACHE var cache = new FusionCache(new FusionCacheOptions()); // SETUP THE DISTRIBUTED 2ND LEVEL cache.SetupDistributedCache(redis, serializer); ``` -------------------------------- ### Install FusionCache Packages Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Backplane.md Installs the necessary NuGet packages for FusionCache, including the core package, a JSON serializer, a distributed cache implementation, and the Redis backplane. ```PowerShell # CORE PACKAGE PM> Install-Package ZiggyCreatures.FusionCache # SERIALIZER PM> Install-Package ZiggyCreatures.FusionCache.Serialization.NewtonsoftJson # DISTRIBUTED CACHE PM> Install-Package Microsoft.Extensions.Caching.StackExchangeRedis # BACKPLANE PM> Install-Package ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis ``` -------------------------------- ### Optimized FusionCache Setup with Shared Redis Connection Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheStampede.md This setup reuses a single Redis connection multiplexer for better performance and resource utilization across serializer, distributed cache, backplane, and distributed locker. It demonstrates efficient configuration for Redis-dependent FusionCache features. ```csharp var muxer = ConnectionMultiplexer.Connect("localhost:6379"); services.AddFusionCache() // SERIALIZER .WithSerializer( new FusionCacheSystemTextJsonSerializer() ) // DISTRIBUTED CACHE .WithDistributedCache( new RedisCache(new RedisCacheOptions { ConnectionMultiplexerFactory = async () => muxer, }) ) // BACKPLANE .WithBackplane( new RedisBackplane(new RedisBackplaneOptions { ConnectionMultiplexerFactory = async () => muxer, }) ) // DISTRIBUTED LOCKER <-- HERE IT IS! .WithDistributedLocker( new RedisDistributedLocker(new RedisDistributedLockerOptions { ConnectionMultiplexerFactory = async () => muxer, }) ); ``` -------------------------------- ### Get or Set Product with Basic Caching Source: https://github.com/ziggycreatures/fusioncache/blob/main/README.md Retrieve a product by ID from the cache, or fetch it from the database and cache it for 30 seconds if not found. ```csharp var id = 42; cache.GetOrSet( $"product:{id}", _ => GetProductFromDb(id), TimeSpan.FromSeconds(30) ); ``` -------------------------------- ### Registering FusionCache with a Custom Memory Locker Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheStampede.md This example demonstrates how to customize FusionCache by providing a specific implementation of the memory locker. This allows for custom logic in coordinating cache access and factory execution. ```csharp services.AddFusionCache() .WithMemoryLocker(new MyMemoryLocker()); ``` -------------------------------- ### Dependency Injection Setup for FusionCache with Redis Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheLevels.md Configures FusionCache with Redis and Newtonsoft Json.NET using Dependency Injection. ```csharp services.AddFusionCache() .WithSerializer( new FusionCacheNewtonsoftJsonSerializer() ) .WithDistributedCache( new RedisCache(new RedisCacheOptions { Configuration = "CONNECTION STRING" }) ) ; ``` -------------------------------- ### Configuring Plugin with DI Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/PluginSample.md Example of how to register and configure the Fail-Safe Email Plugin using the custom DI extension method with strongly-typed options. ```csharp services.AddFusionCacheFailSafeEMailPlugin(options => { options.FromAddress = "sender@example.org"; options.ToAddress = "target@example.org"; options.SmtpHost = "smtp.ethereal.email"; options.SmtpPort = 587; options.SmtpUsername = "[USERNAME]"; options.SmtpPassword = "[PASSWORD]"; }); ``` -------------------------------- ### Register FusionCache with Auto Setup Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Update_v0_20_0.md Use this to maintain previous behavior after updating to v0.20.0. It ensures FusionCache automatically sets up compatible components. ```csharp services.AddFusionCache().TryWithAutoSetup(); ``` -------------------------------- ### Fixed Duration Caching (Without Adaptive Caching) Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/AdaptiveCaching.md This example demonstrates a fixed cache duration of 1 minute for a product entry. Use this when the cache duration is known and does not depend on the cached data. ```csharp var id = 42; // WITHOUT ADAPTIVE CACHING: THE DURATION IS FIXED TO 1 MIN var product = cache.GetOrSet( $"product:{id}", ct => GetProductFromDb(id, ct), options => options.SetDuration(TimeSpan.FromMinutes(1)) // FIXED: 1 MIN ); ``` -------------------------------- ### Basic Distributed Locker Setup with Redis Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheStampede.md Configure FusionCache to use a Redis-based distributed locker with a simple connection string. This is a minimal setup for distributed stampede protection. ```csharp services.AddFusionCache() // ... .WithDistributedLocker( new RedisDistributedLocker(new RedisDistributedLockerOptions { Configuration = "localhost:6379", }) ); ``` -------------------------------- ### FusionCache DI Registration with Options (Pre v0.20.0) Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Update_v0_20_0.md Example of registering FusionCache with specific options before v0.20.0. This method implicitly handled component auto-detection. ```csharp services.AddFusionCache(opt => { opt.AutoRecoveryMaxItems = 123; }); ``` -------------------------------- ### Example of a versioned cache key Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheLevels.md Illustrates how FusionCache appends a version prefix (e.g., 'v2:') to cache keys for distributed caches to manage wire format changes. ```text v2:foo ``` -------------------------------- ### Create FusionCache with a Specific Logger Instance Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Logging.md After creating a logger instance using a LoggerFactory, this example demonstrates how to pass that logger to the FusionCache constructor. If no logger is provided, FusionCache will not log any information. ```csharp var logger = factory.CreateLogger(); var cache = new FusionCache(new FusionCacheOptions(), logger: logger); ``` ```csharp var cache = new FusionCache(new FusionCacheOptions()); ``` -------------------------------- ### Setting a cache entry with tags Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheLevels.md Example of setting a cache entry with a value and associated tags. This demonstrates how FusionCache prepares data for storage, including metadata. ```csharp cache.Set("foo", 123, tags: ["tag-1", "tag-2"]) ``` -------------------------------- ### Get or Set Product with Advanced Caching Options Source: https://github.com/ziggycreatures/fusioncache/blob/main/README.md Cache a product with specific options including high priority, 2-hour fail-safe, 100ms factory soft timeout, and 2s factory hard timeout. ```csharp cache.GetOrSet( $"product:{id}", _ => GetProductFromDb(id), // THIS IS WHERE THE MAGIC HAPPENS options => options .SetDuration(TimeSpan.FromSeconds(30)) .SetPriority(CacheItemPriority.High) .SetFailSafe(true, TimeSpan.FromHours(2)) .SetFactoryTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(2)) ); ``` -------------------------------- ### GetOrDefault Examples Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CoreMethods.md Demonstrates various uses of GetOrDefault to retrieve cached values with default fallbacks. Useful for simple caching where the distinction between a missing value and a default value is not critical. ```csharp // THIS WILL GET BACK 42 foo = cache.GetOrDefault("foo", 42); // IF WE IMMEDIATELY CALL THIS, WE WILL GET BACK 21 foo = cache.GetOrDefault("foo", 21); // THIS WILL GET BACK 0, WHICH IS THE DEFAULT VALUE FOR THE TYPE int foo = cache.GetOrDefault("foo"); // ALSO USEFUL FOR USER PREFERENCES: WE CAN USE A DEFAULT VALUE WITHOUT SETTING ONE var enableUnicorns = cache.GetOrDefault("flags.unicorns", false); // AND SINCE false IS THE DEFAULT VALUE FOR THE TYPE bool WE CAN SIMPLY DO THIS var enableUnicorns = cache.GetOrDefault("flags.unicorns"); ``` -------------------------------- ### Expire Example Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CoreMethods.md Shows how to use the Expire method to logically remove an entry, keeping it available as a stale fallback under specific conditions. Useful when a value should be treated as removed but might be needed later. ```csharp cache.Set("foo", 42, opt => opt.SetDuration(TimeSpan.FromSeconds(10)).SetFailSafe(true)); cache.Expire("foo"); // THIS WILL GET BACK 0, WHICH IS THE DEFAULT VALUE FOR THE TYPE int foo = cache.GetOrDefault("foo"); // THIS WILL GET BACK 42 foo = cache.GetOrDefault("foo", opt => opt.SetAllowStaleOnReadOnly(true)); ``` -------------------------------- ### GetOrSet with Fail-Safe and Soft Timeout Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Timeouts.md This example demonstrates enabling fail-safe and setting a soft factory timeout. If the factory exceeds the specified timeout, FusionCache will temporarily return a stale value while the factory continues in the background. ```csharp product = cache.GetOrSet( "product:123", _ => GetProductFromDb(123), options => options .SetDuration(TimeSpan.FromMinutes(2)) // ENABLE FAIL-SAFE .SetFailSafe(true) // SET A 100 MS SOFT TIMEOUT .SetFactoryTimeouts(TimeSpan.FromMilliseconds(100)) ); ``` -------------------------------- ### Cache Key Collision Example Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/NamedCaches.md Illustrates a potential cache key collision scenario where different named caches might use the same cache key. This highlights the need for mechanisms like `CacheKeyPrefix` to prevent data corruption. ```csharp _productsCache.Set("Foo123", myProduct) _customersCache.Set("Foo123", myCustomer) ``` -------------------------------- ### Skip Cache Writes with Adaptive Caching Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/AdaptiveCaching.md Use adaptive caching to conditionally skip writing to memory and distributed caches based on product properties. This example also demonstrates setting cache durations dynamically. ```csharp var id = 42; // USE ADAPTIVE CACHING TO SKIP CACHE WRITE FOR SOME VALUES RETURNED BY THE FACTORY var product = cache.GetOrSet( $"product:{id}", (ctx, ct) => { var product = GetProductFromDb(id, ct); if (product.IsFlashSale) { // FLASH‑SALE PRODUCTS CHANGE PRICE AND STOCK CONSTANTLY // SO WE AVOID CACHING THEM TO PREVENT SERVING STALE DATA ctx.Options.SkipMemoryCacheWrite = true; ctx.Options.SkipDistributedCacheWrite = true; } else if (product is null) { // CACHE null FOR 5 MIN ctx.Options.Duration = TimeSpan.FromMinutes(5); } else if (product.LastUpdatedAt > DateTime.UtcNow.AddDays(-1)) { // CACHE PRODUCTS UPDATED IN THE LAST DAY FOR 1 MIN ctx.Options.Duration = TimeSpan.FromMinutes(1); } else if (product.LastUpdatedAt > DateTime.UtcNow.AddDays(-10)) { // CACHE PRODUCTS UPDATED IN THE LAST 10 DAYS FOR 10 MIN ctx.Options.Duration = TimeSpan.FromMinutes(10); } else { // CACHE ANY OLDER PRODUCT FOR 30 MIN ctx.Options.Duration = TimeSpan.FromMinutes(30); } return product; }, options => options.SetDuration(TimeSpan.FromMinutes(1)) // DEFAULT: 1 MIN ); ``` -------------------------------- ### Integrate OpenTelemetry with FusionCache Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/StepByStep.md This snippet shows how to add FusionCache instrumentation to OpenTelemetry for tracing and metrics. It includes setup for both traces and metrics, with console exporters as an example. ```csharp services.AddOpenTelemetry() // SETUP TRACES .WithTracing(tracing => tracing .AddFusionCacheInstrumentation() .AddConsoleExporter() // OR ANY ANOTHER EXPORTER ) // SETUP METRICS .WithMetrics(metrics => metrics .AddFusionCacheInstrumentation() .AddConsoleExporter() // OR ANY ANOTHER EXPORTER ); ``` -------------------------------- ### Complete Logging Configuration Example Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Logging.md Demonstrates setting a global minimum log level to Warning and then overriding specific FusionCache factory log levels. Factory synthetic timeouts are set to Debug to be ignored, ensuring less background noise in logs. ```csharp services.AddLogging(b => b // GLOBAL MIN LEVEL: Warning .SetMinimumLevel(LogLevel.Warning) ); services.AddFusionCache() .WithOptions(options => { // FACTORY SYNTHETIC TIMEOUTS: Debug (SO THEY WILL BE IGNORED) options.FactorySyntheticTimeoutsLogLevel = LogLevel.Debug; // ANY OTHER FACTORY ERRORS: Error (SO THEY WILL -NOT- BE IGNORED) options.FactoryErrorsLogLevel = LogLevel.Error; }) ; ``` -------------------------------- ### Implementing Conditional Refresh with ETag Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/ConditionalRefresh.md This example demonstrates how to use stale values and ETags within a factory to perform conditional GET requests. If the server responds with NotModified, the stale value is returned; otherwise, the new value and ETag are saved. ```csharp var product = await cache.GetOrSetAsync( "product:" + id, aSync (ctx, ct) => { using var req = new HttpRequestMessage(HttpMethod.Get, $"/api/product/{id}"); if (ctx.HasETag && ctx.HasStaleValue) { // ETAG + STALE VALUE -> TRY WITH A CONDITIONAL GET req.Headers.Add("If-None-Match", ctx.ETag); } using var resp = await client.SendAsync(req, ct); if (resp.StatusCode == HttpStatusCode.NotModified) { // NOT MODIFIED -> RETURN STALE VALUE return ctx.NotModified(); } resp.EnsureSuccessStatusCode(); // NORMAL RESPONSE: SAVE ETAG + RETURN VALUE return ctx.Modified( await resp.Content.ReadFromJsonAsync(), resp.Headers.ETag?.ToString() ); }, opt => opt.SetDuration(duration).SetFailSafe(true) ); ``` -------------------------------- ### Configure FusionCache with Options and Defaults Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Update_v0_20_0.md Demonstrates chaining builder methods after TryWithAutoSetup() to customize FusionCache behavior. Use Options() to set general cache options and WithDefaultEntryOptions() to configure default settings for cache entries. ```csharp services.AddFusionCache() .TryWithAutoSetup() .WithOptions(opt => { opt.AutoRecoveryMaxItems = 123; }) .WithDefaultEntryOptions(opt => { opt.Duration = TimeSpan.FromSeconds(30); opt.FactorySoftTimeout = TimeSpan.FromMilliseconds(100); }); ``` -------------------------------- ### Configuring Default, Products, and Customers Caches Differently Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/NamedCaches.md Configure each cache (default, 'Products', 'Customers') with distinct entry options, serializers, and distributed cache providers. This allows for tailored caching strategies for different data types or services. ```csharp // DEFAULT CACHE services.AddFusionCache() .WithDefaultEntryOptions(opt => { opt.Duration = TimeSpan.FromSeconds(10); }); // PRODUCTS CACHE services.AddFusionCache("Products") .WithDefaultEntryOptions(opt => { opt.Duration = TimeSpan.FromSeconds(20); }) .WithSerializer(new FusionCacheSystemTextJsonSerializer()) .WithDistributedCache(new RedisCache(new RedisCacheOptions { Configuration = "PRODUCTS_CACHE_CONNECTION" })); // CUSTOMERS CACHE services.AddFusionCache("Customers") .WithDefaultEntryOptions(opt => { opt.Duration = TimeSpan.FromSeconds(30); }) .WithSerializer(new FusionCacheSystemTextJsonSerializer()) .WithDistributedCache(new RedisCache(new RedisCacheOptions { Configuration = "CUSTOMERS_CACHE_CONNECTION" })); ``` -------------------------------- ### Configure Cache and Default Entry Options Together Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/DependencyInjection.md Demonstrates chaining multiple configuration methods on the IFusionCacheBuilder to set both cache-wide options and default entry options. ```csharp services.AddFusionCache() .WithOptions(opt => { opt.AutoRecoveryMaxItems = 123; }) .WithDefaultEntryOptions(opt => { opt.Duration = TimeSpan.FromSeconds(30); opt.FactorySoftTimeout = TimeSpan.FromMilliseconds(100); }) ; ``` -------------------------------- ### Warning Level Logging Output Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Logging.md This example shows the log output when the minimum logging level is set to 'Warning'. It includes fewer details compared to verbose logging, focusing on significant events like synthetic timeouts and fail-safe activations. ```text [12:15:41 WRN] FUSION (O=33859d31231f48a197950c3edd0cccbd K=foo): a synthetic timeout occurred while calling the factory ZiggyCreatures.Caching.Fusion.SyntheticTimeoutException: The operation has timed out. at ZiggyCreatures.Caching.Fusion.Internals.FusionCacheExecutionUtils.RunAsyncFuncWithTimeoutAsync[TResult](Func`2 asyncFunc, TimeSpan timeout, Boolean cancelIfTimeout, Action`1 timedOutTaskProcessor, CancellationToken token) in C:\Users\Jody\source\repos\ZiggyCreatures.FusionCache\src\ZiggyCreatures.FusionCache\Internals\FusionCacheExecutionUtils.cs:line 79 at ZiggyCreatures.Caching.Fusion.FusionCache.GetOrSetEntryInternalAsync[TValue](String operationId, String key, Func`3 factory, MaybeValue`1 failSafeDefaultValue, FusionCacheEntryOptions options, CancellationToken token) in C:\Users\Jody\source\repos\ZiggyCreatures.FusionCache\src\ZiggyCreatures.FusionCache\FusionCache_Async.cs:line 191 [12:15:41 WRN] FUSION (O=33859d31231f48a197950c3edd0cccbd K=foo): FAIL-SAFE activated (from memory) ``` -------------------------------- ### Get or Set Cache Entry with Factory Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/AGentleIntroduction.md This snippet shows how to retrieve a cache entry or set it using a factory function if it doesn't exist. It specifies the cache key, the factory function to get the data (e.g., from a database), and options to set the duration. FusionCache ensures only one factory per key executes concurrently to prevent cache stampede. ```csharp var id = 42; var product = cache.GetOrSet( $"product:{id}", _ => GetProductFromDb(id), // THIS IS THE FACTORY options => options.SetDuration(TimeSpan.FromMinutes(1)) ); ``` -------------------------------- ### Using Default Entry Options for Set Operation Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Options.md Demonstrates how the cache uses the pre-configured default entry options when a Set operation is performed without explicit options. The default duration and fail-safe settings will be applied. ```csharp // THIS USES THE DEFAULT OPTIONS cache.Set("foo", 42); ``` -------------------------------- ### L1 + L2 + Backplane Cache Flow (Simplified) Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Diagrams.md Illustrates the GetOrSet flow including optional L2 and backplane for multi-node synchronization. Cache stampede protection is omitted for simplicity. ```mermaid flowchart TD START[GetOrSet] --> CHECK_L1{✅ Value in L1?} CHECK_L1 -->| Yes | RETURN CHECK_L1 -->| No | CHECK_L2 CHECK_L2{✅ Value in L2?} CHECK_L2 -->| Yes | SAVE_L1 CHECK_L2 -->| No | FACTORY SAVE_L1[💾 Save to L1] SAVE_L1 --> RETURN FACTORY[⚡ Execute factory] FACTORY --> FACTORY_SAVE_L1 FACTORY_SAVE_L1[💾 Save to L1] FACTORY_SAVE_L1 --> SAVE_L2 SAVE_L2[💾 Save to L2] SAVE_L2 --> SEND_BACKPLANE SEND_BACKPLANE[📢 Send backplane notification] SEND_BACKPLANE --> RETURN RETURN[Return value] ``` -------------------------------- ### Cache key with prefix and versioning Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheLevels.md Demonstrates the combined effect of a CacheKeyPrefix and wire format versioning on the final distributed cache key. ```text v2:MyPrefix:foo ``` -------------------------------- ### Remove Example Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CoreMethods.md Demonstrates the usage of the Remove method to delete a cache entry by its key. This is a straightforward operation to clear specific data from the cache. ```csharp cache.Set("foo", 42); // THIS WILL REMOVE THE CACHE ENTRY FOR "foo" cache.Remove("foo"); // THIS WILL DO NOTHING cache.Remove("foo"); ``` -------------------------------- ### Register FusionCache as HybridCache Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/MicrosoftHybridCache.md Configure FusionCache to be available as an implementation of the HybridCache abstraction using dependency injection. This is a one-line addition to your existing FusionCache setup. ```csharp services.AddFusionCache() .AsHybridCache(); // MAGIC ``` -------------------------------- ### Configure Logging for Dependency Injection with FusionCache Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/Logging.md This example illustrates how to configure logging services for a .NET application using Dependency Injection. It sets the minimum log level to Warning and adds the simple console sink with scope inclusion. FusionCache will automatically use the configured logger when registered with AddFusionCache(). ```csharp services.AddLogging(b => b .SetMinimumLevel(LogLevel.Warning) .AddSimpleConsole(options => options.IncludeScopes = true) ); services.AddFusionCache(); ``` -------------------------------- ### Get or Set Product with Overridden Duration Source: https://github.com/ziggycreatures/fusioncache/blob/main/README.md Retrieve a product, using the globally defined default entry options but overriding only the duration for this specific call. ```csharp var id = 42; cache.GetOrSet( $"product:{id}", _ => GetProductFromDb(id), options => options.SetDuration(TimeSpan.FromSeconds(30)) ); ``` -------------------------------- ### Instantiating Plugin without DI Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/PluginSample.md Demonstrates how to manually instantiate the Fail-Safe Email Plugin and add it to Fusion Cache when not using dependency injection. ```csharp var myPlugin = new FailSafeEMailPlugin(new FailSafeEMailPluginOptions() { FromAddress = "sender@example.org", ToAddress = "target@example.org", SmtpHost = "smtp.ethereal.email", SmtpPort = 587, SmtpUsername = "[USERNAME]", SmtpPassword = "[PASSWORD]" }); var cache = new FusionCache(new FusionCacheOptions()); cache.AddPlugin(myPlugin); ``` -------------------------------- ### FusionCache Setup with In-Memory Cache for Serialization Testing Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CacheLevels.md Configures FusionCache with an in-memory distributed cache and Newtonsoft Json.NET serializer to catch serialization issues early during development. ```csharp builder.Services.AddFusionCache() .WithDefaultEntryOptions(new FusionCacheEntryOptions { SkipMemoryCacheRead = true, }) .WithDistributedCache( new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions())) ) .WithSerializer( new FusionCacheNewtonsoftJsonSerializer() // OR ANOTHER ONE OF YOUR CHOOSING ); ``` -------------------------------- ### Get or Set Cache Entry with Default Value Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/CoreMethods.md Retrieves a value from the cache by key. If the value is not found or expired, it sets the provided default value in the cache and returns it. ```csharp var foo = cache.GetOrSet("foo", 123); ``` -------------------------------- ### Implement FusionCache Plugin Source: https://github.com/ziggycreatures/fusioncache/blob/main/docs/PluginSample.md This C# code defines a plugin that listens for fail-safe activation events. It registers an event handler in the Start method and removes it in the Stop method. ```csharp using System; using ZiggyCreatures.Caching.Fusion.Events; namespace ZiggyCreatures.Caching.Fusion.Plugins.MyAwesomePlugins { public class FailSafeEMailPlugin : IFusionCachePlugin { public void Start(IFusionCache cache) { // ADD THE HANDLER cache.Events.FailSafeActivate += OnFailSafeActivate; } public void Stop(IFusionCache cache) { // REMOVE THE HANDLER cache.Events.FailSafeActivate -= OnFailSafeActivate; } private void OnFailSafeActivate(object sender, FusionCacheEntryEventArgs e) { // DO SOMETHING HERE... } } } ```