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.
IConfiguration configurationto yourConfigureServicesmethod along withIServiceCollection. Once you do that you'll be able to use the config settings you want in your Fusion configuration.