Skip to main content
İki paket birlikte hibrit cache stratejisini oluşturur:
  • BuildingBlocks.CachingIHybridRequestCache soyutlaması; Microsoft.Extensions.Caching.Hybrid (HybridCache) üzerine stampede protection + tag-based invalidation + multi-instance broadcast hook ekler.
  • BuildingBlocks.Caching.Redis — L2 backend’i; IDistributedCache implementasyonları ve distributed lock sağlar.
Üst seviye cache mimarisi (L1/L2 stratejisi, invalidation, multi-instance) Cache Mimarisi grubunda anlatılır. Bu sayfa paket arayüzlerine odaklanır.

IHybridRequestCache

HybridCache’i doğrudan inject etmek yerine bu arayüz kullanılır — domain-friendly imza ve multi-instance broadcast hook için.
MetotİmzaAmaç
GetOrCreateAsync<T>ValueTask<T> GetOrCreateAsync<T>(string key, Func<CancellationToken, ValueTask<T>> factory, HybridCacheEntryOptions? options = null, IReadOnlyCollection<string>? tags = null, CancellationToken = default)Cache’te varsa döner, yoksa factory’yi çağırır (stampede-safe)
RemoveAsyncValueTask RemoveAsync(string key, CancellationToken = default)Tek key’i L1+L2’den siler (diğer instance’ların L1’ini etkilemez)
RemoveByTagAsyncValueTask RemoveByTagAsync(string tag, CancellationToken = default)Bir tag’e bağlı tüm entry’leri invalidate eder (lazy); broadcast açıksa diğer node’lara yayılır
RemoveByTagsAsyncValueTask RemoveByTagsAsync(IReadOnlyCollection<string> tags, CancellationToken = default)Toplu tag invalidation
RemoveByTagLocallyAsyncValueTask RemoveByTagLocallyAsync(string tag, CancellationToken = default)Sadece local invalidation — tekrar broadcast yapmaz (loop önleme; integration event handler’ında kullanılır)

CacheOptions

Cache bölümüne bind edilir. Yalnızca spec/DB query cache’ini (CachedRepository) etkiler; auth/token cache’leri (UserContext, JWKS, PKCE) HybridCache’i doğrudan kullanır ve bu bayraklardan etkilenmez.
ÜyeTipVarsayılanAçıklama
EnabledboolSpec/DB query cache kill-switch’i. false ise CachedRepository raw EFCore’a düşer
L1CacheTierOptionsTtl = 1 dkIn-process memory katmanı
L2CacheTierOptionsTtl = 5 dkRedis katmanı (spec WithCacheTtl(...) ile per-entry override edebilir)
BroadcastTagInvalidationboolfalseMulti-instance L1 senkronu için integration event yayını
IRemoteTagBroadcaster çok-instance tag broadcast kontratıdır; varsayılan NoopRemoteTagBroadcaster (tek-node). Multi-pod’da Application katmanı bunu MassTransit/Redis pub-sub implementasyonuyla değiştirir.

DI kaydı — AddCache

public static IServiceCollection AddCache(this IServiceCollection services, IConfiguration configuration)
{
    services.Configure<CacheOptions>(o => configuration.GetSection("Cache").Bind(o));
    services.AddMemoryCache();
    services.AddSingleton<IHybridRequestCache, HybridRequestCache>();
    services.TryAddSingleton<IRemoteTagBroadcaster, NoopRemoteTagBroadcaster>();
    return services;
}
{
  "Cache": {
    "Enabled": true,
    "L1": { "Ttl": "00:01:00" },
    "L2": { "Ttl": "00:05:00" },
    "BroadcastTagInvalidation": false
  }
}
Kayıt sırası kritiktir. HybridCache, L2 backend’i (IDistributedCache, Redis) önceden register edilmiş olmasını bekler. Doğru sıra:
builder.Services.AddRedisCache(builder.Configuration);   // 1. L2 backend (IDistributedCache)
builder.Services.AddCache(builder.Configuration);        // 2. IHybridRequestCache + CacheOptions
builder.Services.AddHybridCache(...);                    // 3. HybridCache — L2'yi görür
AddCache HybridCache’i kendisi register etmezProgram.cs AddHybridCache(...)’ı AddRedisCache’ten sonra çağırır. Sıra bozulursa HybridCache L2’yi göremez ve L1-only çalışır.

BuildingBlocks.Caching.Redis

L2 backend’i ve distributed lock sağlayan paket.
ArayüzAmaç
IDistributedCacheGeneric tipli get/set; pattern bazlı toplu get
IDistributedRequestCacheRequest-scoped cache
IDistributedDatabaseCacheDB query sonucu cache’i
IDistributedSocketCacheWebSocket/SignalR mesaj cache’i
IDistributedLockMutexerIDistributedLock üreten distributed mutex (auto-renew)
RedisDatabaseEnumMantıksal Redis DB seçimi (0-15)
DistributedLockOptions: RedisDistributedLocking (aç/kapa), Expiry (lock TTL — Expiry/2’de auto-renew).

DI kaydı — AddRedisCache

builder.Services.AddRedisCache(builder.Configuration);
{
  "ConnectionStrings": { "RedisConnection": "redis:6379" },
  "Redis": {
    "InstanceName": "dca:",
    "DistributedLock": { "RedisDistributedLocking": true, "Expiry": 30 }
  }
}

Kullanım

// Spec üzerinde cache (Repository.ListAsync ile)
var spec = new GetActiveFaqsSpecification()
    .EnableCache("faqs:active")
    .WithCacheTtl(TimeSpan.FromMinutes(10))
    .WithTags("faq");

var faqs = await _readRepository.ListAsync(spec, ct);

// Doğrudan IHybridRequestCache
var profile = await _cache.GetOrCreateAsync(
    key: $"user:{id}:profile",
    factory: async ct => await _db.GetProfileAsync(id, ct),
    tags: new[] { $"user:{id}" },
    cancellationToken: ct);

// Tag invalidation (domain event handler içinde)
await _cache.RemoveByTagAsync("faq", ct);

// Distributed lock
await using var @lock = await _locker.AcquireLockAsync("batch:123", TimeSpan.FromSeconds(30));
// kritik bölüm — lock dispose'a kadar auto-renew olur

İlgili

Hibrit cache

L1/L2 katman davranışı ve stampede protection.

Invalidation

Tag-based eviction ve domain event entegrasyonu.

Multi-instance

Broadcast ile node’lar arası L1 senkronu.

Specification

Spec üzerinde EnableCache/WithTags entegrasyonu.