2

I'd like to load file data into cache memory on program.cs(.net core 6.0) and loaded data will use in many services.

So I typed builder.Services.AddMemoryCache(); into source code.

But and then, I don't know how to use this memory cache in right there(in program.cs).

In the previous version, with Configure method and IMemoryCache cache parameter I can load data with memory cache like following code block

public void Configure(IMemoryCache cache)
{
    cache.set(...);
    cache.get(...);
}

I'm developing with .net core 6.0 web api. Does anybody know how to init data on program.cs in .net core 6.0?

takeyourcode
  • 375
  • 4
  • 17
  • So you want to write an `IHostedService` / `BackgroundService` to run on host startup? Though you might want to wait until `IHostApplicationLifetime.ApplicationStarted` if you want to handle requests while warming up the cache. – Jeremy Lakeman May 17 '22 at 01:01
  • @JeremyLakeman Thanks for your reply. I'm new to handle .net core framework. I'm studying now. So can you suggest any link that I can learn to write `IHostService`/`BackgroundService` ? – takeyourcode May 17 '22 at 01:05
  • The first google result is a good place to start. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio Which shows a couple common use cases, covering many FAQ. – Jeremy Lakeman May 17 '22 at 01:07
  • @JeremyLakeman Thank you! I'm just curious about this... Is this the general way to init data on starting server? – takeyourcode May 17 '22 at 01:09
  • For lazy init after the api is available, there's also https://stackoverflow.com/a/66996436/4139809, but that's harder to unit test. – Jeremy Lakeman May 17 '22 at 01:14

1 Answers1

6

Below is a work demo, you can refer to it.

Option 1

Do it after the web host is built, in Program.cs:

...
builder.Services.AddMemoryCache();
var app = builder.Build();
var cache=app.Services.GetRequiredService<IMemoryCache>();
cache.Set("key1", "value1");
...

Option 2

Use a hosted service to intialize cache:

public class InitializeCacheService : IHostedService
    {
        private readonly IServiceProvider _serviceProvider;
        public InitializeCacheService (IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            using (var scope = _serviceProvider.CreateScope())
            {
                var cache = _serviceProvider.GetService<IMemoryCache>();

                cache.Set("key1", "value1");
            }

            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }
    }

In Program.cs, add below code:

builder.Services.AddMemoryCache();
builder.Services.AddHostedService<InitializeCacheService>();

ValuesController (Two options all use this controller)

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly IMemoryCache _cache;
        public ValuesController(IMemoryCache cache)
        {
            _cache = cache;

        }
        [HttpGet("{key}")]
        public ActionResult<string> Get(string key)
        {
            //_cahce.Count is 0
            if (!_cache.TryGetValue(key, out var value))
            {
                return NotFound($"The value with the {key} is not found");
            }

            return value + "";
        }
    }

Result:

enter image description here

Update enter image description here

Qing Guo
  • 6,041
  • 1
  • 2
  • 10
  • Thank you for perfect answer. I really impressed. – takeyourcode May 17 '22 at 05:06
  • I tried to apply option 1, but It didn't worked. What is different for your answer, I wrapped requiredservice line and cache.set/get line with `using (var scope = app.Services.CreateScope())` . Is it problem? – takeyourcode May 17 '22 at 05:08
  • Can you share more code you used? And the error you meet ? @takeyourcode – Qing Guo May 17 '22 at 05:29
  • `using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; var context = services.GetRequiredService(); context.Set("test", "aaaaaa"); Console.WriteLine(context.Get("test")); } ` And console output was empty but your solution working well. Is it problem? – takeyourcode May 17 '22 at 05:43
  • @takeyourcode I try your code, but console output has aaaaaa. – Qing Guo May 17 '22 at 05:55
  • Gua It is so weird.. Ok anyway I'll try it again. And I'll try your option 2 for my skill as well. Good luck to you! – takeyourcode May 17 '22 at 15:52
  • It was my mistake.. I checked It is working well. Really thanks for your reply! – takeyourcode May 17 '22 at 16:21