Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Persistent in-memory concurrent dictionary in ASP.NET Core

In an ASP.NET Core application, I would like to have persistent, shared state that is analogous to:

ConcurrentDictionary<string, Job> Jobs;

Various components of the applications will access this shared state (request handling controllers, background tasks), but my main concern isn't concurrent access. What I'm curious about is whether there is a way to persist a global variable like this throughout the lifetime of my ASP.NET Core application.

Is there a place I can define this global Jobs variable where it will not be destroyed by the ASP.NET Core runtime? Perhaps leveraging MemoryCache in some way?

Using something like Redis would certainly work, but I'm curious if there is a robust in-memory/in-process solution for global shared state in ASP.NET Core.

like image 282
mmnormyle Avatar asked Mar 05 '23 02:03

mmnormyle


1 Answers

You can wrap ConcurrentDictionary within a class and register it as singleton.

public class SharedJobs
{
    private readonly ConcurrentDictionary<string, Job> _jobs
        = new ConcurrentDictionary<string, Job>();

    public ConcurrentDictionary<string, Job> Jobs => _jobs;
}

In Startup.cs

services.AddSingleton<SharedJobs>();

Usage

public class Service
{
    private readonly SharedJobs _shared;

    public Service(SharedJobs shared) => _shared = shared;

    public void DoSomething()
    {
        var job = _shared.Jobs.GetOrAdd("Key", new Job("New Job when not found"));
    }
}

You can go further and hide the fact that you are using ConcurrentDictionary under the hood and expose only required functionality to the consumers.

public class SharedJobs
{
    private readonly ConcurrentDictionary<string, Job> _jobs
        = new ConcurrentDictionary<string, Job>();

    public Job Get(string key)
    {
        return _jobs.GetOrAdd(key, CreateNewJob());
    }

    private Job CreateNewJob() {}
}
like image 50
Fabio Avatar answered Mar 07 '23 01:03

Fabio