diff --git a/src/ZiggyCreatures.FusionCache/FusionCacheBuilderExtMethods.cs b/src/ZiggyCreatures.FusionCache/FusionCacheBuilderExtMethods.cs index c2b286c8..7d3d1852 100644 --- a/src/ZiggyCreatures.FusionCache/FusionCacheBuilderExtMethods.cs +++ b/src/ZiggyCreatures.FusionCache/FusionCacheBuilderExtMethods.cs @@ -75,22 +75,43 @@ public static IFusionCacheBuilder WithOptions(this IFusionCacheBuilder builder, if (action is null) throw new ArgumentNullException(nameof(action)); - builder.SetupOptionsAction += action; - - return builder; - } - - /// - /// Set the cache key prefix to use. - ///

- /// EXAMPLE: if the CacheKeyPrefix specified is "MyCache:", a later call to cache.GetOrDefault("Product/123") will actually work on the cache key "MyCache:Product/123". - ///

- /// DOCS: - ///
- /// The to act upon. - /// The cache key prefix to use. - /// The so that additional calls can be chained. - public static IFusionCacheBuilder WithCacheKeyPrefix(this IFusionCacheBuilder builder, string? cacheKeyPrefix) + builder.SetupOptionsAction += (s, o) => action(o); + + return builder; + } + + /// + /// Specify a custom logic to further configure the instance to be used. + ///

+ /// DOCS: + ///
+ /// The to act upon. + /// The custom action that configure the object. + /// The so that additional calls can be chained. + public static IFusionCacheBuilder WithOptions(this IFusionCacheBuilder builder, Action action) + { + if (builder is null) + throw new ArgumentNullException(nameof(builder)); + + if (action is null) + throw new ArgumentNullException(nameof(action)); + + builder.SetupOptionsAction += action; + + return builder; + } + + /// + /// Set the cache key prefix to use. + ///

+ /// EXAMPLE: if the CacheKeyPrefix specified is "MyCache:", a later call to cache.GetOrDefault("Product/123") will actually work on the cache key "MyCache:Product/123". + ///

+ /// DOCS: + ///
+ /// The to act upon. + /// The cache key prefix to use. + /// The so that additional calls can be chained. + public static IFusionCacheBuilder WithCacheKeyPrefix(this IFusionCacheBuilder builder, string? cacheKeyPrefix) { if (builder is null) throw new ArgumentNullException(nameof(builder)); diff --git a/src/ZiggyCreatures.FusionCache/IFusionCacheBuilder.cs b/src/ZiggyCreatures.FusionCache/IFusionCacheBuilder.cs index 2b34bd85..848a9692 100644 --- a/src/ZiggyCreatures.FusionCache/IFusionCacheBuilder.cs +++ b/src/ZiggyCreatures.FusionCache/IFusionCacheBuilder.cs @@ -91,7 +91,7 @@ public interface IFusionCacheBuilder /// /// A custom setup logic for the object, to allow for fine-grained customization. /// - Action? SetupOptionsAction { get; set; } + Action? SetupOptionsAction { get; set; } #endregion diff --git a/src/ZiggyCreatures.FusionCache/Internals/Builder/FusionCacheBuilder.cs b/src/ZiggyCreatures.FusionCache/Internals/Builder/FusionCacheBuilder.cs index 5ebca17b..e7a56135 100644 --- a/src/ZiggyCreatures.FusionCache/Internals/Builder/FusionCacheBuilder.cs +++ b/src/ZiggyCreatures.FusionCache/Internals/Builder/FusionCacheBuilder.cs @@ -53,7 +53,7 @@ public FusionCacheBuilder(string cacheName, IServiceCollection services) public bool UseCacheKeyPrefix { get; set; } public bool AddCacheKeyPrefixSeparator { get; set; } public string? CacheKeyPrefix { get; set; } - public Action? SetupOptionsAction { get; set; } + public Action? SetupOptionsAction { get; set; } public FusionCacheEntryOptions? DefaultEntryOptions { get; set; } public Action? SetupDefaultEntryOptionsAction { get; set; } @@ -143,7 +143,7 @@ public IFusionCache Build(IServiceProvider serviceProvider) } } - SetupOptionsAction?.Invoke(options); + SetupOptionsAction?.Invoke(serviceProvider, options); // CACHE KEY PREFIX if (UseCacheKeyPrefix) diff --git a/src/ZiggyCreatures.FusionCache/Internals/DistributeLocker/DistributedLockerAccessor.cs b/src/ZiggyCreatures.FusionCache/Internals/DistributeLocker/DistributedLockerAccessor.cs index c2cc7e0f..e5d2373a 100644 --- a/src/ZiggyCreatures.FusionCache/Internals/DistributeLocker/DistributedLockerAccessor.cs +++ b/src/ZiggyCreatures.FusionCache/Internals/DistributeLocker/DistributedLockerAccessor.cs @@ -33,8 +33,15 @@ public IFusionCacheDistributedLocker DistributedLocker } private string GetLockName(string key) - { - return $"{key}{_options.InternalStrings.DistributedLockerLockNameSuffix}"; + { + var lockName = $"{key}{_options.InternalStrings.DistributedLockerLockNameSuffix}"; + + if (_options.CacheKeyPrefix is not null) + { + lockName = _options.CacheKeyPrefix + lockName; + } + + return lockName; } //private void UpdateLastError(string operationId, string key) diff --git a/tests/ZiggyCreatures.FusionCache.Tests/DependencyInjectionTests.cs b/tests/ZiggyCreatures.FusionCache.Tests/DependencyInjectionTests.cs index 5b8e9a96..6488f7be 100644 --- a/tests/ZiggyCreatures.FusionCache.Tests/DependencyInjectionTests.cs +++ b/tests/ZiggyCreatures.FusionCache.Tests/DependencyInjectionTests.cs @@ -169,6 +169,30 @@ public void CannotSpecifyCacheNameOfNamedCacheViaOptions() }); } + [Fact] + public void CanSpecifyCacheKeyPrefixOfNamedCacheViaOptionsAndDI() + { + var services = new ServiceCollection(); + + services.AddKeyedSingleton("cachePrefix", "foo_prefix"); + + services.AddFusionCache("foo") + .WithOptions((sp, opt) => + { + opt.CacheKeyPrefix = sp.GetRequiredKeyedService("cachePrefix"); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + var cacheProvider = serviceProvider.GetRequiredService(); + + var cache = cacheProvider.GetCache("foo"); + + Assert.NotNull(cache); + Assert.Equal("foo", cache.CacheName); + Assert.Equal("foo_prefix", cache.GetOptions().CacheKeyPrefix); + } + [Fact] public void CanDirectlyAddANamedCacheInstance() {