0

I am using an ASP.NET Core 9.0 Web API with C#. My application setup uses L1 Cache using FusionAPI and L2 is Garnet Server for distributed layer of cache. The following code snippet is from my Startup.cs class.

Some of my configurations are coming from SQL as this is a business requirement. I have simplified the code shown here:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDbConnectionFactory, DbConnectionFactory>();
    services.AddSingleton<ISqlRepository, SqlRepository>();

    ConfigParamStore paramStore = null;

    using (var tempProvider = services.BuildServiceProvider())
    {
        var sqlRepo = tempProvider.GetRequiredService<ISqlRepository>();
        paramStore = sqlRepo.GetConfigParamStoreAsync().GetAwaiter().GetResult();
    }

    var garnetConnectionString = paramStore[ConfigParamNames.GarnetServerConnectionString].GetValueAsString();

    var sslHostName = paramStore[ConfigParamNames.GarnetServerSslHostName].GetValueAsString();
    
    ConfigurationOptions garnetConfigOptions = new ConfigurationOptions
    {
        EndPoints = { garnetConnectionString },
        User = paramStore[ConfigParamNames.GarnetServerAclUserName].GetValueAsString(),
        Password = paramStore[ConfigParamNames.GarnetServerAclPassword].GetValueAsString(),
        Ssl = true,
        SslHost = sslHostName,

        ConnectTimeout = paramStore[ConfigParamNames.GarnetServerConnectionTimeoutInMilliseconds].GetValueAsInt(), 
        SyncTimeout = paramStore[ConfigParamNames.GarnetServerSyncTimeoutInMilliseconds].GetValueAsInt(),
        ConnectRetry = paramStore[ConfigParamNames.GarnetServerConnectionRetries].GetValueAsInt(),
        AllowAdmin = false
    };

    var connectionMultiplexer = ConnectionMultiplexer.Connect(garnetConfigOptions);

    services.AddControllers().AddOData(opt => { });
    services.AddHttpContextAccessor();
    
    // Removed other configurations to keep code small.
    services.AddSingleton<IFusionCacheSerializer, FusionCacheNewtonsoftJsonSerializer>();
    services.AddFusionCache()
        .WithDistributedCache(new RedisCache(new RedisCacheOptions
        {
            ConfigurationOptions = garnetConfigOptions
        }))
        .WithDefaultEntryOptions(new FusionCacheEntryOptions
        {
            Duration = TimeSpan.FromMilliseconds(paramStore[ConfigParamNames.FusionCacheDurationInMilliseconds].GetValueAsInt()),
            DistributedCacheDuration = TimeSpan.FromMilliseconds(paramStore[ConfigParamNames.GarnetCacheDurationInMilliseconds].GetValueAsInt()),
            
            AllowTimedOutFactoryBackgroundCompletion = true,

            IsFailSafeEnabled = true,
            FailSafeMaxDuration = TimeSpan.FromMilliseconds(paramStore[ConfigParamNames.FusionFailSafeMaxDurationInMilliseconds].GetValueAsInt()),
            DistributedCacheFailSafeMaxDuration = TimeSpan.FromMilliseconds(paramStore[ConfigParamNames.GarnetFailSafeMaxDurationInMilliseconds].GetValueAsInt()),
            FailSafeThrottleDuration = TimeSpan.FromMilliseconds(paramStore[ConfigParamNames.GarnetFailSafeThrottleDurationInMilliseconds].GetValueAsInt()),

            ReThrowDistributedCacheExceptions = true
        });

    services.AddSingleton<IConnectionMultiplexer>(connectionMultiplexer);
}

My question is: how can I avoid writing this line of code:

 var tempProvider = services.BuildServiceProvider()

I want to avoid this line, and I want to initialize paramStore bit late so that all DIs would be proper, but in this case how would I use the database values in method services.AddFusionCache() ?

Variable paramStore is fetching and holding values from the SQL database, which is used in initializing the properties of method call services.AddFusionCache().

How to fetch the values from the database and still not doing early initialization like this:

using (var tempProvider = services.BuildServiceProvider())

Please guide.

3
  • 1
    None of this code is needed (and doesn't work as it should anyway). .NET can load settings from multiple configuration sources, including custom ones. You can create custom configuration providers easily. In fact, loading settings from the database is the example used in Implement a custom configuration provider in .NET. The example uses EF to load objects but nothing prevents you from using eg Dapper Commented Aug 4 at 16:46
  • @PanagiotisKanavos: Thanks for your help. I have seen your provided link and honestly, did not get much. I am newbie in .NET core, can you please help me what is the right way to do this configuration? Commented Aug 4 at 16:51
  • 1
    The docs aren't complicated, while the code you just wrote is. Read and actually follow the docs. In all supported .NET versions the configuration is already accessible - you should be able to pass an IConfiguration configuration to your ConfigureServices method along with IServiceCollection. Once you do that you'll be able to use the config settings you want in your Fusion configuration. Commented Aug 4 at 16:59

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.