DEV Community

Alex
Alex

Posted on

.NET Learning Notes: How to use Redis in ASP.NET

1. Install NuGet package

dotnet add package StackExchange.Redis
Enter fullscreen mode Exit fullscreen mode

2. Configuration connection string

Here, I config it in appsettings.json

  "ConnectionStrings": {
    "Redis": "localhost:6379"
  }
Enter fullscreen mode Exit fullscreen mode

3. Configure connectiong string in Program.cs

builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
{
    var redisCon = builder.Configuration.GetConnectionString("Redis")!;
    var configuration = ConfigurationOptions.Parse(redisCon, true);
    configuration.ResolveDns = true;
    return ConnectionMultiplexer.Connect(configuration);
});
Enter fullscreen mode Exit fullscreen mode

4. DI IConnectionMultiplexer to service

public class BasicJwtTokenValidationMiddleware
{
    private readonly RequestDelegate _next;
    private readonly List<string> _authWhiteList;
    private readonly IConnectionMultiplexer _redis;

    public BasicJwtTokenValidationMiddleware(RequestDelegate next, 
        IOptions<AuthenticationOptions> authOptions,
        IConnectionMultiplexer redis)
    {
        _next = next;
        _authWhiteList = authOptions.Value.AuthWhiteList;
        _redis = redis;
    }

    public Task Invoke(HttpContext context)
    {
      // *****
      var redisVersion = await _redis.GetDatabase().StringGetAsync($"jwt:version:{userPublicId}");

      // ***
    }
}
Enter fullscreen mode Exit fullscreen mode

5. How to mock it in unit test (use AutoFixture + Moq)

[Theory, AutoMoqData]
public async Task IsValidVersionAsync_ReturnsTrue_WhenVersionMatches(
    [Frozen] Mock<IConnectionMultiplexer> redisMock,
    [Frozen] Mock<IDatabase> dbMock)
{
    // Arrange
    var userId = "user-123";
    var version = "3";

    dbMock.Setup(db => db.StringGetAsync($"jwt:version:{userId}", It.IsAny<CommandFlags>()))
        .ReturnsAsync(version);

    redisMock.Setup(r => r.GetDatabase(It.IsAny<int>(), null))
        .Returns(dbMock.Object);
}
Enter fullscreen mode Exit fullscreen mode

Why do we mock GetDatabase with parameters even though we call it without parameters in code?

Answer: Because GetDatabase uses default parameter values in C#;
Method definition of GetDatabase:

IDatabase GetDatabase(int db = -1, object? asyncState = null);
Enter fullscreen mode Exit fullscreen mode

So, if we mock with our parameters like:redisMock.Setup(c => c.GetDatabase()). It won't match the actual call to GetDatabase(-1, null)

Top comments (0)