Rystem.RepositoryFramework.Cache.Azure.Storage.Blob
10.0.7
dotnet add package Rystem.RepositoryFramework.Cache.Azure.Storage.Blob --version 10.0.7
NuGet\Install-Package Rystem.RepositoryFramework.Cache.Azure.Storage.Blob -Version 10.0.7
<PackageReference Include="Rystem.RepositoryFramework.Cache.Azure.Storage.Blob" Version="10.0.7" />
<PackageVersion Include="Rystem.RepositoryFramework.Cache.Azure.Storage.Blob" Version="10.0.7" />
<PackageReference Include="Rystem.RepositoryFramework.Cache.Azure.Storage.Blob" />
paket add Rystem.RepositoryFramework.Cache.Azure.Storage.Blob --version 10.0.7
#r "nuget: Rystem.RepositoryFramework.Cache.Azure.Storage.Blob, 10.0.7"
#:package Rystem.RepositoryFramework.Cache.Azure.Storage.Blob@10.0.7
#addin nuget:?package=Rystem.RepositoryFramework.Cache.Azure.Storage.Blob&version=10.0.7
#tool nuget:?package=Rystem.RepositoryFramework.Cache.Azure.Storage.Blob&version=10.0.7
Rystem.RepositoryFramework.Cache.Azure.Storage.Blob
Rystem.RepositoryFramework.Cache.Azure.Storage.Blob adds a Blob Storage-backed distributed cache adapter for Repository Framework decorators.
It does not cache entities directly inside your main repository storage. Instead, it registers a dedicated internal repository for BlobStorageCacheModel and uses Azure Blob Storage as the persistence layer for cache entries.
Installation
dotnet add package Rystem.RepositoryFramework.Cache.Azure.Storage.Blob
This package builds on top of:
Rystem.RepositoryFramework.CacheRystem.RepositoryFramework.Infrastructure.Azure.Storage.Blob
How it works
Calling WithBlobStorageCache(...) does two things:
- registers an internal
IRepository<BlobStorageCacheModel, string>backed by the Blob Storage infrastructure package - wires
BlobStorageCache<T, TKey>as the distributed cache decorator for your repository, query, or command registration
Each cached value is stored as a blob containing:
Expirationas aDateTimeValueas serialized JSON
At read time the adapter:
- checks whether the cache blob exists
- downloads the blob
- compares
ExpirationwithDateTime.UtcNow - deserializes the stored JSON payload when still valid
If the entry is expired, the adapter simply returns a cache miss. The current implementation does not automatically delete the stale blob during that read.
Basic repository example
builder.Services.AddRepository<User, string>(repositoryBuilder =>
{
repositoryBuilder.WithBlobStorage(storage =>
{
storage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
storage.Settings.ContainerName = "users";
});
repositoryBuilder.WithBlobStorageCache(
cacheStorage =>
{
cacheStorage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
cacheStorage.Settings.ContainerName = "user-cache";
cacheStorage.Settings.Prefix = "cache/";
},
cache =>
{
cache.ExpiringTime = TimeSpan.FromMinutes(5);
cache.Methods = RepositoryMethods.Get
| RepositoryMethods.Query
| RepositoryMethods.Exist;
});
});
This keeps your domain data container separate from your cache container, which is usually the cleanest setup.
CQRS registrations
The package exposes overloads for all three Repository Framework patterns.
Repository
builder.Services.AddRepository<Document, Guid>(repositoryBuilder =>
{
repositoryBuilder.WithBlobStorage(storage =>
{
storage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
});
repositoryBuilder.WithBlobStorageCache(cacheStorage =>
{
cacheStorage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
cacheStorage.Settings.ContainerName = "document-cache";
});
});
Query only
builder.Services.AddQuery<User, string>(queryBuilder =>
{
queryBuilder.WithBlobStorage(storage =>
{
storage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
});
queryBuilder.WithBlobStorageCache(
cacheStorage =>
{
cacheStorage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
cacheStorage.Settings.ContainerName = "user-query-cache";
},
cache =>
{
cache.ExpiringTime = TimeSpan.FromMinutes(30);
cache.Methods = RepositoryMethods.Get | RepositoryMethods.Query;
});
});
Command only
As with the base cache package, write caching on command-only registrations is meaningful only when Methods includes write flags.
builder.Services.AddCommand<User, string>(commandBuilder =>
{
commandBuilder.WithBlobStorage(storage =>
{
storage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
});
commandBuilder.WithBlobStorageCache(
cacheStorage =>
{
cacheStorage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
cacheStorage.Settings.ContainerName = "user-command-cache";
},
cache =>
{
cache.ExpiringTime = TimeSpan.FromMinutes(10);
cache.Methods = RepositoryMethods.Insert
| RepositoryMethods.Update
| RepositoryMethods.Delete;
});
});
Two-level cache example
You can stack the standard in-memory decorator in front of Blob Storage.
builder.Services.AddRepository<User, string>(repositoryBuilder =>
{
repositoryBuilder.WithBlobStorage(storage =>
{
storage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
storage.Settings.ContainerName = "users";
});
repositoryBuilder.WithInMemoryCache(cache =>
{
cache.ExpiringTime = TimeSpan.FromSeconds(30);
cache.Methods = RepositoryMethods.Get | RepositoryMethods.Query;
});
repositoryBuilder.WithBlobStorageCache(
cacheStorage =>
{
cacheStorage.Settings.ConnectionString = builder.Configuration["ConnectionStrings:Storage"];
cacheStorage.Settings.ContainerName = "user-cache";
},
cache =>
{
cache.ExpiringTime = TimeSpan.FromMinutes(10);
cache.Methods = RepositoryMethods.All;
});
});
Read flow in that setup:
- try in-memory cache
- try Blob Storage distributed cache
- hit the underlying repository
- repopulate missed layers
Blob-specific behavior
The Blob Storage cache adapter is intentionally small and inherits most behavior from the base cache package.
Important details from the source:
- cache values are serialized with
System.Text.Json SetAsync(...)writes throughUpdateAsync(...)on the internal blob repository- because the blob repository uses
UploadAsync(..., overwrite: true), cache writes behave like upserts DeleteAsync(...)first checks whether the cache blob exists and then deletes it- the cache repository key type is always
string
Naming and factory behavior
WithBlobStorageCache(...) accepts the same optional name parameter used across Repository Framework registrations.
That name is used for two different things:
- selecting the decorated repository/query/command registration
- naming the internal
IRepository<BlobStorageCacheModel, string>factory registration created for the cache backend
This means named registrations are supported, but the same caveats from the base cache package still apply:
GetandExistcache keys include the factory nameQueryandOperationcache keys do not include the factory name in the current implementation
If you have multiple named registrations for the same model and they expose different data sources, avoid query caching or keep their cache backends physically separate.
Cache options
This package uses DistributedCacheOptions<T, TKey> from Rystem.RepositoryFramework.Cache.
| Property | Default | Notes |
|---|---|---|
Methods |
Query | Get | Exist |
Enables read-through caching by default. |
ExpiringTime |
365 * 365 days |
Set this explicitly for production workloads. |
Relevant flags:
GetcachesGetAsyncExistcachesExistAsyncQuerycachesQueryAsyncandOperationAsyncInsert,Update, andDeletekeep key-based cache entries in syncAllenables every flag
As with the base cache package, write operations update Get and Exist entries for affected keys, but they do not invalidate previously cached query result sets.
Choosing containers and prefixes
The cache storage registration uses the same Blob Storage builder as the main Azure Blob infrastructure package, so you can configure:
ConnectionStringEndpointUriManagedIdentityClientIdContainerNamePrefixClientOptions
Using a dedicated container like user-cache is usually easier to inspect and rotate than mixing cache blobs with domain blobs.
When to use this package
Use it when you want:
- a distributed cache layer without bringing in Redis or SQL Server cache infrastructure
- cache entries that can be shared across app instances through Azure Blob Storage
- a cache backend configured with the same Blob Storage connection model already used by Repository Framework storage packages
If you want the generic cache decorators without Blob Storage, start with ../RepositoryFramework.Cache/README.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Rystem.RepositoryFramework.Cache (>= 10.0.7)
- Rystem.RepositoryFramework.Infrastructure.Azure.Storage.Blob (>= 10.0.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.7 | 83 | 3/26/2026 |
| 10.0.6 | 188,119 | 3/3/2026 |
| 10.0.5 | 98 | 2/22/2026 |
| 10.0.4 | 109 | 2/9/2026 |
| 10.0.3 | 147,877 | 1/28/2026 |
| 10.0.1 | 209,064 | 11/12/2025 |
| 9.1.3 | 243 | 9/2/2025 |
| 9.1.2 | 764,442 | 5/29/2025 |
| 9.1.1 | 97,807 | 5/2/2025 |
| 9.0.32 | 186,713 | 4/15/2025 |
| 9.0.31 | 5,791 | 4/2/2025 |
| 9.0.30 | 88,808 | 3/26/2025 |
| 9.0.29 | 9,014 | 3/18/2025 |
| 9.0.28 | 249 | 3/17/2025 |
| 9.0.27 | 263 | 3/16/2025 |
| 9.0.26 | 255 | 3/13/2025 |
| 9.0.25 | 52,128 | 3/9/2025 |
| 9.0.21 | 321 | 3/6/2025 |
| 9.0.20 | 19,601 | 3/6/2025 |
| 9.0.19 | 311 | 3/6/2025 |