Skip to content

Add support for keyed IDistributedCache in AddStackExchangeRedisCache #63700

@eerhardt

Description

@eerhardt

Background and Motivation

We have been finding scenarios where developers need multiple IDistributedCache instances in a single application. For example:

One concrete example is to have 2 IDistributedCache instances, one pointing to Redis and one pointing to a SqlServer. Another example is 2 caches talking to different instances of Redis.

Proposed API

namespace Microsoft.Extensions.DependencyInjection;

public static class StackExchangeRedisCacheServiceCollectionExtensions
{
    public static IServiceCollection AddStackExchangeRedisCache(this IServiceCollection services, Action<RedisCacheOptions> setupAction);
+   public static IServiceCollection AddKeyedStackExchangeRedisCache(this IServiceCollection services, object? key, Action<RedisCacheOptions> setupAction);
+   public static IServiceCollection AddKeyedStackExchangeRedisCache(this IServiceCollection services, object? serviceKey, string optionsName, Action<RedisCacheOptions> setupAction);
}

This follows the same API approach (the optional optionsName) as proposed in dotnet/runtime#117976

Usage Examples

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddKeyedStackExchangeRedisCache("cache1", options =>
{
    options.Configuration = "redis1:6379";
    options.InstanceName = "SampleInstance1";
});

builder.Services.AddKeyedStackExchangeRedisCache(typeof(MyCache), "myCacheOptionsName", options =>
{
    options.Configuration = "redis2:6379";
    options.InstanceName = "SampleInstance2";
});

var app = builder.Build();

var cache1 = app.Services.GetRequiredKeyedService<IDistributedCache>("cache1");
var cache2 = app.Services.GetRequiredKeyedService<IDistributedCache>(typeof(MyCache));

Alternative Designs

Risks

The current approach being employed is to create a new RedisCache instance (since the ctor is public). However, the when using AddStackExchangeRedisCache today it uses an internal derived type: RedisCacheImpl.

As of .NET 10, the drawback to this approach is that it doesn't use the internal RedisCacheImpl class. Which means:

  • The RedisCache won't log appropriately (but it only logs in one place - where it is unable to add library name suffix).
  • If HybridCache is being used, it won't add the 'HC' library name suffix to the connection. Since the check only happens in RedisCacheImpl.

FYI @mgravell @jeffhandley @captainsafia

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-middlewareIncludes: URL rewrite, redirect, response cache/compression, session, and other general middlewaresfeature-cachingIncludes: StackExchangeRedis and SqlServer distributed caches

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions