Redis Caching

When your application grows beyond a single server, Redis is the gold standard for distributed caching. It’s fast, scalable, and accessible from anywhere—perfect for microservices, cloud deployments, and high-availability scenarios.

REN.Kit.CacheKit makes using Redis cache in your .NET 8 or .NET 9 projects not only straightforward, but enterprise-ready. You get high performance, reliability, and all the power of Redis, with a developer-friendly interface.


1. Configuration: Define Redis Settings in appsettings.json

Before using Redis, add the following configuration block to your appsettings.json:

"CacheConfiguration": {
  "RedisConfiguration": {
    "Url": "localhost:6379",
    "TimeConfiguration": {
      "AbsoluteExpirationInHours": 12
    },
    "DatabaseId": 4,
    "Username": "default",
    "Password": "ofqa9YpQ6iw5tmDsoH5EW1OTMJtKs2Gs",
    "AbortOnConnectFail": false,
    "IsAdmin":  false
  }
}
  • Url: Address of your Redis server (can be remote or localhost)

  • AbsoluteExpirationInHours: The max lifetime for a cache entry

  • DatabaseId: Redis logical database (usually 0)

  • Username/Password: For secured Redis clusters

  • AbortOnConnectFail: Should connections be retried or fail fast

  • IsAdmin: (Optional) Set to true if you want to allow administrative operations like FlushDb.

circle-exclamation

⚠️ Security Tip:


2. Service Registration

After configuring your Redis cache, register REN.Kit for Redis in your Program.cs:

You can now inject IRENCacheService into your classes and use Redis for high-performance, distributed caching.

Here’s how the core registration works under the hood:


3. Why the Multiplexer Factory and Lifetime Are Provided by the Consumer

When registering Redis caching with REN.Kit, the library does not create the ConnectionMultiplexer internally. Instead, it asks you to provide:

  • a factory: Func<IServiceProvider, IConnectionMultiplexer>

  • a lifetime: RedisMultiplexerLifetime (Singleton / Scoped / Transient)

There are several reasons for this design.

3.1. Full Control Over How Redis Is Configured

Every application has different requirements for how Redis is wired:

  • Configuration may come from appsettings.json, environment variables, Vault, Consul, or feature flags.

  • You might need to configure SSL, certificates, custom timeouts, sentinel, or cluster endpoints.

  • Some applications already have a shared IConnectionMultiplexer used by other libraries.

By accepting a Func<IServiceProvider, IConnectionMultiplexer>, REN.Kit:

  • does not assume where or how you load your settings,

  • lets you use anything already registered in DI (IConfiguration, ILogger, IOptions<T>, etc.),

  • avoids hard-coding ConnectionMultiplexer.Connect(...) logic inside the library.

This keeps configuration logic in your application, where it belongs, and keeps the caching library provider-agnostic and clean.

3.2. Correct Lifetime Management (Singleton / Scoped / Transient)

ConnectionMultiplexer is a heavy, expensive object that manages connections, pooling, and reconnections. StackExchange.Redis recommends treating it as a long-lived, shared object, typically a singleton.

However, not all applications are the same:

  • A web API or microservice usually wants one singleton multiplexer shared across the entire app.

  • A multi-tenant system might want:

    • a scoped multiplexer per tenant or per request in special cases, or

    • multiple multiplexers for different Redis clusters.

  • Some advanced / edge scenarios may even want transient multiplexers (e.g., testing, short-lived tools).

By exposing RedisMultiplexerLifetime:

  • The library does not guess what your lifecycle should be.

  • You, as the application developer, explicitly choose:

    • RedisMultiplexerLifetime.Singleton

    • RedisMultiplexerLifetime.Scoped

    • RedisMultiplexerLifetime.Transient

Internally, REN.Kit just translates this into the appropriate DI registration:

This gives you fine-grained control while keeping the API very simple on the library side.

✅ In most real-world applications, RedisMultiplexerLifetime.Singleton is the recommended choice.

3.3. Testability and Extensibility

Because the multiplexer is provided from the outside:

  • In unit tests, you can register a fake or mocked IConnectionMultiplexer without touching REN.Kit’s internals.

  • In integration tests, you can swap the real Redis instance with a local container, a different connection string, or a test cluster.

  • In the future, if you want to:

    • route to a different Redis cluster,

    • switch to another implementation that still exposes IConnectionMultiplexer,

    you can do this without changing the library or its public API.

This makes the library easier to maintain, extend, and integrate into complex architectures.

3.4. Clear Separation of Responsibilities

The design follows a simple rule:

  • Your application is responsible for:

    • how to connect to Redis,

    • how long the connection should live,

    • where configuration comes from.

  • REN.Kit is responsible for:

    • how to use Redis once a multiplexer exists,

    • providing a clean IRENCacheService abstraction,

    • integrating with DI in a consistent way.

By keeping responsibilities separated, the library remains:

  • framework-agnostic (minimal assumptions),

  • future-proof (no hard-coded Redis configuration),

  • and easy to reason about for other developers reading your code.


Why Choose Redis Cache?

  • Scalable: Multiple app instances can share the same cache instantly.

  • High Availability: Use with Redis Sentinel or clustering for failover.

  • Lightning Fast: Network lookups in microseconds, with optional persistence.

  • Perfect for:

    • Distributed session storage

    • User authentication tokens

    • Large data objects shared across services

    • Rate limiting, leaderboards, and more

circle-check

Pro Tips:

circle-exclamation

Why is Clear() supported for Redis, but not for In-Memory?

Last updated