A lightweight wrapper around StackExchange.Redis that provides seamless dependency injection integration for .NET applications with automatic key prefixing and centralized configuration.
- 🚀 Quick DI Setup — Register Redis client in one line of code
- 🔑 Automatic Key Prefixing — Isolate data by environment and application name
- ⚙️ Type-Safe Configuration — Strongly-typed
RedisOptionsclass - 🔗 Singleton Connection — Single
IConnectionMultiplexerinstance per application - 🛡️ Redis Sentinel Support — Built-in support for high-availability setups
- 📦 Full StackExchange.Redis Access — No limitations on Redis commands
- 🎯 Native AOT Compatible — Fully compatible with Native AOT compilation
Install-Package Monq.Core.RedisAdd Redis configuration to your appsettings.json:
{
"Redis": {
"EndPoints": [
{
"Host": "localhost",
"Port": 6379
}
],
"Password": "your-password",
"DbNum": 0
}
}In Program.cs or Startup.cs:
using Microsoft.Extensions.DependencyInjection;
// ...
builder.Services.AddRedisClient(builder.Configuration.GetSection("Redis"));Inherit from RedisClientBase to get automatic connection and key prefixing:
using Monq.Core.Redis.RedisClient;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
public class WeatherCacheService : RedisClientBase
{
public WeatherCacheService(
IRedisConnectionFactory connectionFactory,
IHostEnvironment env,
IConfiguration configuration)
: base(connectionFactory, env, configuration)
{
}
public string GetWeatherDescription(string id)
{
return Db.HashGet(KeyPrefix + ":weather", id).ToString();
}
public void SetWeatherDescription(string id, string description)
{
Db.HashSet(KeyPrefix + ":weather", id, description);
}
public bool DeleteWeatherDescription(string id)
{
return Db.HashDelete(KeyPrefix + ":weather", id);
}
}[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly WeatherCacheService _weatherCacheService;
public WeatherForecastController(WeatherCacheService weatherCacheService)
{
_weatherCacheService = weatherCacheService;
}
[HttpGet("GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
var description = _weatherCacheService.GetWeatherDescription("test");
// ...
}
}{
"Redis": {
"EndPoints": [
{
"Host": "redis-server.com",
"Port": 6379
}
]
}
}{
"Redis": {
"EndPoints": [
{
"Host": "redis1.com",
"Port": 6379
},
{
"Host": "redis2.com",
"Port": 6379
}
],
"Password": "password",
"DbNum": 1,
"AbortOnConnectFail": false,
"AllowAdmin": false,
"ChannelPrefix": null,
"ClientName": "my-app",
"ConfigCheckSeconds": 60,
"ConnectRetry": 3,
"ConnectTimeout": 5000,
"DefaultDatabase": null,
"KeepAlive": 60,
"User": "myuser",
"Proxy": "None",
"ResolveDns": false,
"ServiceName": "mymaster",
"Ssl": false,
"SslHost": null,
"SslProtocols": "Tls12,Tls13",
"AsyncTimeout": 0,
"SyncTimeout": 0,
"TieBreaker": "",
"DefaultVersion": "2.0",
"CheckCertificateRevocation": true,
"KeyPrefix": "myapp"
}
}| Property | Type | Description |
|---|---|---|
EndPoints |
Array | Redis server endpoints (host and port) |
Password |
string | Authentication password |
DbNum |
int | Database number (0-15) |
AbortOnConnectFail |
bool | If true, fails immediately when no servers are available |
AllowAdmin |
bool | Enables administrative commands |
ClientName |
string | Connection identifier in Redis |
ConnectTimeout |
int | Connection timeout in milliseconds |
KeepAlive |
int | Keep-alive interval in seconds |
User |
string | Username for Redis ACL (Redis 6+) |
ServiceName |
string | Sentinel master service name |
Ssl |
bool | Enable SSL encryption |
SslProtocols |
string | SSL/TLS versions (e.g., "Tls12,Tls13") |
KeyPrefix |
string | Custom prefix for all keys |
SyncTimeout |
int | Timeout for synchronous operations |
AsyncTimeout |
int | Timeout for asynchronous operations |
The library automatically generates key prefixes to isolate data between environments:
- Default behavior:
{EnvironmentName}:{ApplicationName}- Example:
Production:my-api
- Example:
- With custom
KeyPrefix:{KeyPrefix}:{ApplicationName}- Example:
myapp:my-api
- Example:
This ensures that development, staging, and production environments don't share cached data.
Set a custom application name via environment variable or configuration:
{
"APPLICATION_NAME": "custom-app-name"
}If you don't want to inherit from RedisClientBase, you can inject IRedisConnectionFactory directly:
public class MyService
{
private readonly IDatabase _db;
public MyService(IRedisConnectionFactory factory)
{
_db = factory.Connection().GetDatabase();
}
public string GetValue(string key)
{
return _db.StringGet(key).ToString();
}
public void SetValue(string key, string value)
{
_db.StringSet(key, value);
}
}{
"Redis": {
"EndPoints": [
{ "Host": "sentinel1.com", "Port": 26379 },
{ "Host": "sentinel2.com", "Port": 26379 },
{ "Host": "sentinel3.com", "Port": 26379 }
],
"ServiceName": "mymaster",
"Password": "password"
}
}public class MessageService : RedisClientBase
{
public MessageService(
IRedisConnectionFactory connectionFactory,
IHostEnvironment env,
IConfiguration configuration)
: base(connectionFactory, env, configuration)
{
}
public void PublishMessage(string channel, string message)
{
var subscriber = Connection.GetSubscriber();
subscriber.Publish(channel, message);
}
public void Subscribe(string channel, Action<string> handler)
{
var subscriber = Connection.GetSubscriber();
subscriber.Subscribe(channel, (ch, msg) => handler(msg));
}
}- .NET 8.0 or higher
- StackExchange.Redis 2.x
- Redis server 3.0 or higher
Problem: Application starts but Redis connection fails silently
Solution: Set AbortOnConnectFail: true to fail fast during development:
{
"Redis": {
"AbortOnConnectFail": true,
"ConnectTimeout": 5000
}
}Problem: Timeout errors on operations
Solution: Increase timeout values:
{
"Redis": {
"SyncTimeout": 5000,
"AsyncTimeout": 5000
}
}Problem: Keys don't have expected prefix
Solution: Ensure you're using KeyPrefix property from base class:
// ✅ Correct
Db.StringSet(KeyPrefix + ":mykey", value);
// ❌ Incorrect
Db.StringSet(":mykey", value);Problem: SSL handshake fails
Solution: Specify SSL protocols explicitly:
{
"Redis": {
"Ssl": true,
"SslProtocols": "Tls12,Tls13",
"SslHost": "redis.example.com"
}
}Before:
var connection = ConnectionMultiplexer.Connect("localhost");
var db = connection.GetDatabase();After:
// In Program.cs
services.AddRedisClient(Configuration.GetSection("Redis"));
// In your service
public class MyService : RedisClientBase
{
public MyService(IRedisConnectionFactory factory, IHostEnvironment env, IConfiguration config)
: base(factory, env, config) { }
// Use Db property directly
}The Auth property is deprecated. Use Password instead:
// ❌ Old (deprecated)
{ "Auth": "password" }
// ✅ New
{ "Password": "password" }See the WebApp sample for a complete working example.
This project is licensed under the MIT License.