Skip to content

Commit c4417a2

Browse files
author
Kelly Yin
committed
Add DI extension method and add UT
1 parent c3adbb4 commit c4417a2

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

src/Libraries/Microsoft.Extensions.Caching.Hybrid/HybridCacheServiceExtensions.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using Microsoft.Extensions.Caching.Distributed;
56
using Microsoft.Extensions.Caching.Hybrid;
67
using Microsoft.Extensions.Caching.Hybrid.Internal;
8+
using Microsoft.Extensions.Caching.Memory;
79
using Microsoft.Extensions.DependencyInjection.Extensions;
10+
using Microsoft.Extensions.Options;
811
using Microsoft.Shared.Diagnostics;
912

1013
namespace Microsoft.Extensions.DependencyInjection;
@@ -41,4 +44,35 @@ public static IHybridCacheBuilder AddHybridCache(this IServiceCollection service
4144
services.TryAddSingleton<HybridCache, DefaultHybridCache>();
4245
return new HybridCacheBuilder(services);
4346
}
47+
48+
/// <summary>
49+
/// Adds support for keyed multi-tier caching services.
50+
/// </summary>
51+
/// <returns>A builder instance that allows further configuration of the <see cref="HybridCache"/> system.</returns>
52+
public static IHybridCacheBuilder AddHybridCache(this IServiceCollection services, string name, Action<HybridCacheOptions> setupAction)
53+
{
54+
_ = Throw.IfNull(services);
55+
_ = Throw.IfNull(name);
56+
_ = Throw.IfNull(setupAction);
57+
58+
// Register options for this key
59+
_ = services.AddOptions<HybridCacheOptions>(name).Configure(setupAction);
60+
61+
// Register keyed in-memory cache
62+
services.TryAddKeyedSingleton<IMemoryCache, MemoryCache>(name);
63+
64+
// Register keyed HybridCache
65+
services.TryAddKeyedSingleton<HybridCache>(name, (sp, _) =>
66+
new DefaultHybridCache(
67+
Options.Options.Create(sp.GetRequiredService<IOptionsMonitor<HybridCacheOptions>>().Get(name)),
68+
sp,
69+
sp.GetKeyedService<IMemoryCache>(name),
70+
sp.GetKeyedService<IDistributedCache>(name)));
71+
72+
services.TryAddSingleton<IHybridCacheSerializerFactory, DefaultJsonSerializerFactory>();
73+
services.TryAddSingleton<IHybridCacheSerializer<string>>(InbuiltTypeSerializer.Instance);
74+
services.TryAddSingleton<IHybridCacheSerializer<byte[]>>(InbuiltTypeSerializer.Instance);
75+
76+
return new HybridCacheBuilder(services);
77+
}
4478
}

test/Libraries/Microsoft.Extensions.Caching.Hybrid.Tests/ServiceConstructionTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
using Microsoft.Extensions.Caching.Hybrid.Internal;
88
using Microsoft.Extensions.Caching.Memory;
99
using Microsoft.Extensions.DependencyInjection;
10+
using Microsoft.Extensions.DependencyInjection.Extensions;
1011
using Microsoft.Extensions.Logging;
1112
using Microsoft.Extensions.Options;
13+
using Microsoft.Extensions.Caching.StackExchangeRedis;
14+
1215

1316
#if NET9_0_OR_GREATER
1417
using Microsoft.Extensions.Configuration;
@@ -51,6 +54,38 @@ public void CanCreateServiceWithManualOptions()
5154
Assert.Null(defaults.LocalCacheExpiration); // wasn't specified
5255
}
5356

57+
[Fact]
58+
public void CanCreateKeyedServicesWithManualOptions()
59+
{
60+
var name = "testName";
61+
var services = new ServiceCollection();
62+
63+
// Mock registering keyed IDistributedCache from client side
64+
services.TryAddKeyedSingleton<IDistributedCache, RedisCache>(name);
65+
66+
services.AddHybridCache(name, options =>
67+
{
68+
options.MaximumKeyLength = 937;
69+
});
70+
using var provider = services.BuildServiceProvider();
71+
72+
var hybridCacheOption = provider.GetRequiredService<IOptionsMonitor<HybridCacheOptions>>().Get(name);
73+
Assert.NotNull(hybridCacheOption);
74+
Assert.Equal(937, hybridCacheOption.MaximumKeyLength);
75+
76+
var memoryCache = provider.GetRequiredKeyedService<IMemoryCache>(name);
77+
Assert.NotNull(memoryCache);
78+
Assert.IsType<MemoryCache>(memoryCache);
79+
80+
var hybridCache = provider.GetRequiredKeyedService<HybridCache>(name);
81+
Assert.NotNull(hybridCache);
82+
Assert.IsType<DefaultHybridCache>(hybridCache);
83+
84+
var backendCache = provider.GetRequiredKeyedService<IDistributedCache>(name);
85+
Assert.NotNull(backendCache);
86+
Assert.IsType<RedisCache>(backendCache);
87+
}
88+
5489
#if NET9_0_OR_GREATER // for Bind API
5590
[Fact]
5691
public void CanParseOptions_NoEntryOptions()

0 commit comments

Comments
 (0)