ZiggyCreatures / FusionCache

FusionCache is an easy to use, fast and robust hybrid cache with advanced resiliency features.
MIT License
1.57k stars 84 forks source link

best way to store FusionCacheEntryOptions in iConfiguration #214

Closed sabbadino closed 3 months ago

sabbadino commented 3 months ago

Problem

Suppose I have an application with many different FusionCacheEntryOptions requirement for different type of items to be cached. I need to store each of such different setting in IConfiguration

it would be nice to reuse the FusionCacheEntryOptions but it is sealed

Solution

If FusionCacheEntryOptions was not sealed i could do something like this

public class MyFusionCacheEntryOptions : FusionCacheEntryOptions {
    // use FusionCacheEntryOptions inherited properties to be used as default in 
    //  builder.Services.AddFusionCache().WithDefaultEntryOptions(

    public List<MyFusionCacheEntryOptionsEntry> CustomCacheSettings { get; init; } = new();
}

public class MyFusionCacheEntryOptionsEntry : FusionCacheEntryOptions {
      public string Name { get; init; } = "";
}

and then I coudl do something like this when i need such settings

 var option = _fusionCacheSettingConfig.CustomCacheSettings.**SingleOrDefault(c => c.Name == "cacheentrytype1");**
   var ret = await _fusionCache.GetOrSetAsync(location, async _ => 
 {
     return await _weatherDataSource.GetCurrentTime(location, throwEx);
 }, **option**);
 return

Alternatives

Is there another declarative, IConfiguration based solution I ma not aware to manage a large set of FusionCacheEntryOptions values ?

pbolduc commented 3 months ago

I suspect the class is sealed for performance reasons. There is nothing stopping you from doing something like this:

        var settings = new Dictionary<string, FusionCacheEntryOptions>();

        string[] names = ["Foo"];
        foreach (var name in names)
        {
            var section = builder.Configuration.GetSection(name);
            var options = new FusionCacheEntryOptions();
            section.Bind(options);

            settings.Add(name, options);
        }

        builder.Services.AddSingleton(settings);

Or you could just wrap the type instead of inheriting from it.

public class NamedFusionCacheEntryOptions
{
    public string Name { get; set; }
    public FusionCacheEntryOptions CacheEntryOptions { get; set; }
}
sabbadino commented 3 months ago

Oh yes, composition over inheritance.. it was actually quite a naive question :)

jodydonetti commented 3 months ago

Hi all, sorry for the delay. Thanks @pbolduc for the hint! @sabbadino did it work?