FusionCache icon indicating copy to clipboard operation
FusionCache copied to clipboard

[FEATURE] Options do not follow .Net standard pattern

Open TibbsTerry opened this issue 10 months ago • 12 comments

Problem

Configuration of options do not follow the standard .Net options pattern Options cannot be set via configuration and have to be 'hard-coded'

services.AddFusionCache()
    .WithOptions(o =>
    {
        // Can not access other dependencies eg IConfiguration here!
        o.DefaultEntryOptions.Duration = duration;
    });
[Test]
public void Test_WithOptions()
{
    var duration = TimeSpan.FromMinutes(50);
    var services = new ServiceCollection();
    services.AddFusionCache()
        .WithOptions(o => o.DefaultEntryOptions.Duration = duration);
    var serviceProvider = services.BuildServiceProvider();
    var fusionCache = serviceProvider.GetRequiredService<IFusionCache>();
    Assert.AreEqual(duration, fusionCache.DefaultEntryOptions.Duration);  // PASS
}

[Test]
public void Test_WithConfiguration()
{
    var duration = TimeSpan.FromMinutes(50);
    var configuration = new ConfigurationBuilder()
        .AddInMemoryCollection(new Dictionary<string, string?>  { { "DefaultDurationMinutes", duration.TotalMinutes.ToString()} })
        .Build();
    var services = new ServiceCollection();
    services.AddSingleton<IConfiguration>(configuration);
    services.AddFusionCache();
    services.AddOptions<FusionCacheOptions>()
        .Configure<IConfiguration>((options, config) =>
        {
            var durationMinutes = long.Parse(config["DefaultDurationMinutes"]!);
            options.DefaultEntryOptions.Duration = TimeSpan.FromMinutes(durationMinutes);
        });
    var serviceProvider = services.BuildServiceProvider();
    var fusionCache = serviceProvider.GetRequiredService<IFusionCache>();
    Assert.AreEqual(duration, fusionCache.DefaultEntryOptions.Duration); // FAIL
}

Solution

Confguration/Options should follow standards for .NET ie should use Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.Configure

Microsoft.Extensions.DependencyInjection.MemoryCacheServiceCollectionExtensions.AddDistributedMemoryCache https://github.com/dotnet/runtime/blob/a5af0ab77caa5ed7a6844fc5f4f459e5edfe23d3/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCacheServiceCollectionExtensions.cs#L93 is probably a good example of how to do it.

or (less preferable solution) change FusionCacheBuilder.SetupOptionsAction to Action<IServiceProvider, FusionCacheOptions>? SetupOptionsAction { get; set; }

TibbsTerry avatar Dec 10 '24 00:12 TibbsTerry