diff --git a/src/DataProtection/StackExchangeRedis/src/PublicAPI.Unshipped.txt b/src/DataProtection/StackExchangeRedis/src/PublicAPI.Unshipped.txt index 7dc5c58110bf..9673342076e9 100644 --- a/src/DataProtection/StackExchangeRedis/src/PublicAPI.Unshipped.txt +++ b/src/DataProtection/StackExchangeRedis/src/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ #nullable enable +static Microsoft.AspNetCore.DataProtection.StackExchangeRedisDataProtectionBuilderExtensions.PersistKeysToStackExchangeRedis(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, System.Func! databaseFactory) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.StackExchangeRedisDataProtectionBuilderExtensions.PersistKeysToStackExchangeRedis(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, System.Func! databaseFactory, StackExchange.Redis.RedisKey key) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! diff --git a/src/DataProtection/StackExchangeRedis/src/RedisDataProtectionBuilderExtensions.cs b/src/DataProtection/StackExchangeRedis/src/RedisDataProtectionBuilderExtensions.cs index 82a8a8c69012..6ac3b2c5f156 100644 --- a/src/DataProtection/StackExchangeRedis/src/RedisDataProtectionBuilderExtensions.cs +++ b/src/DataProtection/StackExchangeRedis/src/RedisDataProtectionBuilderExtensions.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.DataProtection.StackExchangeRedis; using Microsoft.AspNetCore.Shared; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using StackExchange.Redis; namespace Microsoft.AspNetCore.DataProtection; @@ -28,7 +29,7 @@ public static IDataProtectionBuilder PersistKeysToStackExchangeRedis(this IDataP { ArgumentNullThrowHelper.ThrowIfNull(builder); ArgumentNullThrowHelper.ThrowIfNull(databaseFactory); - return PersistKeysToStackExchangeRedisInternal(builder, databaseFactory, key); + return PersistKeysToStackExchangeRedisInternal(builder, _ => databaseFactory(), key); } /// @@ -53,15 +54,44 @@ public static IDataProtectionBuilder PersistKeysToStackExchangeRedis(this IDataP { ArgumentNullThrowHelper.ThrowIfNull(builder); ArgumentNullThrowHelper.ThrowIfNull(connectionMultiplexer); - return PersistKeysToStackExchangeRedisInternal(builder, () => connectionMultiplexer.GetDatabase(), key); + return PersistKeysToStackExchangeRedisInternal(builder, _ => connectionMultiplexer.GetDatabase(), key); + } + + /// + /// Configures the data protection system to persist keys to the default key ('DataProtection-Keys') in Redis database + /// + /// The builder instance to modify. + /// A factory function that uses to create an instance. + /// A reference to the after this operation has completed. + public static IDataProtectionBuilder PersistKeysToStackExchangeRedis(this IDataProtectionBuilder builder, Func databaseFactory) + { + return PersistKeysToStackExchangeRedis(builder, databaseFactory, DataProtectionKeysName); + } + + /// + /// Configures the data protection system to persist keys to the specified key in Redis database + /// + /// The builder instance to modify. + /// A factory function that uses to create an instance. + /// The used to store key list. + /// A reference to the after this operation has completed. + public static IDataProtectionBuilder PersistKeysToStackExchangeRedis(this IDataProtectionBuilder builder, Func databaseFactory, RedisKey key) + { + ArgumentNullThrowHelper.ThrowIfNull(builder); + ArgumentNullThrowHelper.ThrowIfNull(databaseFactory); + return PersistKeysToStackExchangeRedisInternal(builder, databaseFactory, key); } - private static IDataProtectionBuilder PersistKeysToStackExchangeRedisInternal(IDataProtectionBuilder builder, Func databaseFactory, RedisKey key) + private static IDataProtectionBuilder PersistKeysToStackExchangeRedisInternal(IDataProtectionBuilder builder, Func databaseFactory, RedisKey key) { - builder.Services.Configure(options => + builder.Services.AddSingleton>(services => { - options.XmlRepository = new RedisXmlRepository(databaseFactory, key); + return new ConfigureOptions(options => + { + options.XmlRepository = new RedisXmlRepository(() => databaseFactory(services), key); + }); }); + return builder; } } diff --git a/src/DataProtection/StackExchangeRedis/test/RedisDataProtectionBuilderExtensionsTest.cs b/src/DataProtection/StackExchangeRedis/test/RedisDataProtectionBuilderExtensionsTest.cs index 34ea9081f2e3..9a5cefd05e60 100644 --- a/src/DataProtection/StackExchangeRedis/test/RedisDataProtectionBuilderExtensionsTest.cs +++ b/src/DataProtection/StackExchangeRedis/test/RedisDataProtectionBuilderExtensionsTest.cs @@ -28,4 +28,21 @@ public void PersistKeysToRedis_UsesRedisXmlRepository() var options = services.GetRequiredService>(); Assert.IsType(options.Value.XmlRepository); } + + [Fact] + public void PersistKeysToRedis_FactoryMethod_UsesRedisXmlRepository() + { + // Arrange + var connection = Mock.Of(); + var serviceCollection = new ServiceCollection(); + var builder = serviceCollection.AddDataProtection(); + + // Act + builder.PersistKeysToStackExchangeRedis(services => services.GetRequiredService().GetDatabase()); + var services = serviceCollection.BuildServiceProvider(); + + // Assert + var options = services.GetRequiredService>(); + Assert.IsType(options.Value.XmlRepository); + } }