Overview
Caching in the Ramsha Framework provides a unified, modular, and provider-agnostic way to store and retrieve cached data across your application.
Ramsha caching is built on top of Microsoft.Extensions.Caching.Hybrid and exposes a simple abstraction that works consistently across all Ramsha engine modes.
Ramsha caching is designed to:
- Be modular and optional
- Decouple application logic from caching infrastructure
- Support both in-memory and distributed caching transparently
At the center of the caching system is the IRamshaCache abstraction.
Default Caching Behavior
When you install and enable only the Ramsha.Caching package:
- Cache entries are stored in memory only
- No external infrastructure is required
- Ideal for:
- Development environments
- Single-instance applications
- Lightweight services
This default behavior works out of the box with zero additional configuration.
Hybrid Cache Concept
Ramsha uses Hybrid Cache, a modern caching abstraction that combines multiple cache layers into a single API.
Hybrid Cache supports:
- Local in-memory cache (L1) for fast access
- Optional distributed cache (L2) for shared storage
The cache resolution flow is:
- Check in-memory cache
- If not found, check distributed cache (if configured)
- If still not found, execute a factory to generate the value
- Store the result back into the cache layers
Ramsha configures Hybrid Cache internally while keeping application code independent of where cached data is stored.
Cache Stampede Protection
Hybrid Cache automatically prevents cache stampedes.
When multiple requests attempt to access the same cache key at the same time:
- Only one factory execution is allowed
- Other callers wait for the result
- Once completed, all callers receive the cached value
This behavior is available even when using in-memory caching only.
Cache Keys and Tags
Cache Keys
Cache keys must uniquely identify cached data.
Best practices:
- Use stable and predictable key formats
- Include identifiers (e.g.
product:42) - Avoid very large keys
Key length limits are configurable through RamshaCachingOptions.
Cache Tags
Ramsha caching supports tag-based invalidation.
Tags allow you to:
- Group related cache entries
- Invalidate multiple entries at once
- Simplify cache cleanup logic
This is especially useful for domain-based cache invalidation.
Enabling Caching
Enable caching by depending on the CachingModule:
- As Service
- Module-based
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRamsha(ramsha =>
{
ramsha.AddCaching(); // or ramsha.AddModule<CachingModule>
});
var app = builder.Build();
app.UseRamsha();
app.Run();
public class MyModule : RamshaModule
{
public override void Register(RegisterContext context)
{
base.Register(context);
context.DependsOn<CachingModule>();
}
}
IRamshaCache Interface
Applications and modules interact with caching through IRamshaCache.
This ensures:
- No dependency on specific caching providers
- Easy testing and replacement
- Clean separation between logic and infrastructure
Common Cache Operations
Get or Create
app.MapGet("products", async (IRamshaCache cache) =>
{
return await cache.GetOrCreateAsync(
"products:all",
async ct => await LoadProductsAsync(),
new RamshaCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(10),
LocalCacheExpiration = TimeSpan.FromMinutes(2)
});
});
This method:
- Reads from cache if available
- Executes the factory only if needed
- Writes results back to cache layers
Set Cache Entry
Sometime you want only to set data to the cache:
await _cache.SetAsync(
"products:all",
products,
new RamshaCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(10)
});
Remove Cache Entry
await _cache.RemoveAsync("products:all");
Remove by Tag
await _cache.RemoveByTagAsync("products");
Configuration
Caching behavior is configured using RamshaCachingOptions, typically during the Prepare phase of a module.
These options control:
- Cache key limits
- Payload size limits
- Default expiration values
- Local vs distributed cache expiration