C
C#3mo ago
RacerDelux

Best Way To Load and Cache Scoped Data?

I am using MediatR, so scoped services essentially live the lifetime of the MediatR request. Given that, I want to load configuration from a database if not loaded (using Entity Framework), then cache the returned data, as it is used multiple times for the request. What is the best way to go about this? This is my current code, but this is blocking and I would think could cause performance issues. This particular example would remove 4 round trip database calls.
public class ScopedCachingService(DbContext context)
{
private Configurations[]? GlobalConfiguration { get; set; }

public Configurations[] GetGlobalConfigurationAsync()
{
return GlobalConfiguration ??= context.Configuration.OrderBy(c => c.ConfigKey).ToArray();
}
}
public class ScopedCachingService(DbContext context)
{
private Configurations[]? GlobalConfiguration { get; set; }

public Configurations[] GetGlobalConfigurationAsync()
{
return GlobalConfiguration ??= context.Configuration.OrderBy(c => c.ConfigKey).ToArray();
}
}
9 Replies
RacerDelux
RacerDeluxOP3mo ago
Further info, each time I use this Configuration table, in 4 different scoped services, they will look something like this:
context.Configuration.where(c => c.key == "some key").FirstorDefaultAsync();
context.Configuration.where(c => c.key == "some key").FirstorDefaultAsync();
Where, in each instance, the configuration key is different
jcotton42
jcotton423mo ago
Well for starters, you could make it async.
RacerDelux
RacerDeluxOP3mo ago
Right, that was part of what I was figuring out. Is it best to make the getter async, or to do a Task.Run on the database call and make that async? For either option, what happens if multiple services make a call to that variable before the initial call returns the value?
jcotton42
jcotton423mo ago
Not sure why you’d use Task.Run here. Right now, for multiple calls, they’d all end up running, and the last would “win” the assignment I guess.
RacerDelux
RacerDeluxOP3mo ago
So really I would want to guarantee that the database call is only run once though right?
jcotton42
jcotton423mo ago
Actually, since you’re using mediatr, maybe you could load this data in a pipeline behavior?
RacerDelux
RacerDeluxOP3mo ago
Now that is something I have not messed with yet - but I assume the pipeline may give me an opportunity to make a call out to data and use it?
jcotton42
jcotton423mo ago
Yes, the behaviors are all async. This does mean that the layer above your pipeline cannot use the config data, but typically that code should be pretty minimal anyhow.
RacerDelux
RacerDeluxOP3mo ago
Yeah, you are correct, its just a line of code to call the mediatR request haha Thanks!
Want results from more Discord servers?
Add your server