Skip to content

Conversation

@kelly-yinn
Copy link
Contributor

@kelly-yinn kelly-yinn commented Aug 7, 2025

Closes dotnet/runtime#117976

Adds support for keyed HybridCache instances in DI, along with the ability to configure the DistributedCacheServiceKey for the hybrid cache to resolve a keyed IDistributedCache service. This opens up the scenario of having multiple hybrid caches within an application, each potentially using a separate backend cache. Those backend caches could be separate databases or entirely separate services. For example, having a Redis-backed cache alongside a SQL Server-backed cache.

    [Fact]
    public void CanCreateRedisAndSqlServerBackedHybridCaches()
    {
        var services = new ServiceCollection();
        services.AddKeyedSingleton<IDistributedCache, RedisCache>("Redis");

        services.AddKeyedSingleton<IDistributedCache, SqlServerCache>("SqlServer",
            (sp, key) => new SqlServerCache(new SqlServerCacheOptions
            {
                ConnectionString = "test",
                SchemaName = "test",
                TableName = "test"
            }));

        services.AddKeyedHybridCache("HybridWithRedis", options => options.DistributedCacheServiceKey = "Redis");
        services.AddKeyedHybridCache("HybridWithSqlServer", options => options.DistributedCacheServiceKey = "SqlServer");

        using ServiceProvider provider = services.BuildServiceProvider();
        var hybridWithRedis = Assert.IsType<DefaultHybridCache>(provider.GetRequiredKeyedService<HybridCache>("HybridWithRedis"));
        var hybridWithRedisBackend = Assert.IsType<RedisCache>(hybridWithRedis.BackendCache);
        Assert.Same(hybridWithRedisBackend, provider.GetRequiredKeyedService<IDistributedCache>("Redis"));

        var hybridWithSqlServer = Assert.IsType<DefaultHybridCache>(provider.GetRequiredKeyedService<HybridCache>("HybridWithSqlServer"));
        var hybridWithSqlServerBackend = Assert.IsType<SqlServerCache>(hybridWithSqlServer.BackendCache);
        Assert.Same(hybridWithSqlServerBackend, provider.GetRequiredKeyedService<IDistributedCache>("SqlServer"));
    }
Microsoft Reviewers: Open in CodeFlow

@kelly-yinn kelly-yinn requested a review from a team as a code owner August 7, 2025 02:08
@jeffhandley jeffhandley marked this pull request as draft August 11, 2025 05:44
@jeffhandley
Copy link
Member

I've marked this PR as a draft as we need to get [Support detect keyed dependency injected IDistributedCache as backend cache for DefaultHybridCache (#117976)](dotnet/runtime#117976) through API review, and tests would need to be added to the PR as well.

I'm getting a .NET 10 RC1/RC2 bar check for this. I'll keep you posted, @ylt1534.

@kelly-yinn

This comment was marked as resolved.

@kelly-yinn kelly-yinn marked this pull request as ready for review August 13, 2025 02:36
@kelly-yinn
Copy link
Contributor Author

Thanks @jeffhandley for the review. I just noticed that the DefaultHybridCache is designed as internal thus unable to DI is outside the lib. I added a new extension method and add some UTs. I want to test that the keyed instances (options, backend cache, memory cache, hybrid cache) are injected into each other correctly, but that might bring more changes like expose the _backendCache and _localCache properties from DefaultHybridCache. For now I tried to make the PR small to be easy review. thanks.

@kelly-yinn kelly-yinn marked this pull request as draft August 15, 2025 08:30
@jeffhandley jeffhandley changed the title Update DefaultHybridCache constructor to support DI localCache and backendCache Support keyed HybridCache with keyed DistributedCaches and named options Sep 15, 2025
@eerhardt
Copy link
Member

Is this going to be an issue?

https://github.com/dotnet/aspnetcore/blob/6f91a7d7be082aa1246f41a884b182637942d5a4/src/Caching/StackExchangeRedis/src/RedisCacheImpl.cs#L16-L17

    internal override bool IsHybridCacheActive()
        => _services.GetService<HybridCache>() is not null;

this code assumes that if there is an unkeyed HybridCache in the service collection, then it should add the HC library name suffix:

https://github.com/dotnet/aspnetcore/blob/6f91a7d7be082aa1246f41a884b182637942d5a4/src/Caching/StackExchangeRedis/src/RedisCache.cs#L381-L383

@jeffhandley
Copy link
Member

@eerhardt and I discussed the IsHybridCacheActive scenario noted above and concluded it's not a blocker here. The implementation of that logging/telemetry is not compatible with having keyed HybridCache services registered, but it's also producing the incorrect result if an application uses a Redis cache and also uses a HybridCache that isn't backed by Redis. That design issue and bug should be addressed separately and in a way that is compatible with keyed hybrid caches.

@jeffhandley jeffhandley marked this pull request as ready for review September 16, 2025 23:53
This was referenced Oct 15, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Oct 17, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Proposal] Support keyed HybridCache with keyed DistributedCaches

4 participants