Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should `StackExchange.Redis.ConnectionMultiplexer` be `AddSingleton` or `AddScope` in .NET Core dependency injection?

I'm adding a Redis connection to .NET Core using StackExchange.Redis, it currently looks something like this:

public static IServiceCollection AddRedisMultiplexer(
    this IServiceCollection services,
    Func<ConfigurationOptions> getOptions = null)
{
    // Get the options or assume localhost, as these will be set in Startup.ConfigureServices assume they won't change
    var options = getOptions?.Invoke() ?? ConfigurationOptions.Parse("localhost");

    // The Redis is a singleton, shared as much as possible.
    return services.AddSingleton<IConnectionMultiplexer>(provider => ConnectionMultiplexer.Connect(options));
}

Then in Startup

public void ConfigureServices(IServiceCollection services)
{
    services.AddRedisMultiplexer(() => 
        ConfigurationOptions.Parse(Configuration["ConnectionStrings:Redis"]));
    ...

This then means I can use IConnectionMultiplexer for the dependency injection anywhere.

My question is: ConnectionMultiplexer is designed to be reused, so I've used AddSingleton to keep a single instance for the entire application. However I could also use AddScoped to use one for the duration of the request. Which is better and why?

like image 529
Keith Avatar asked Nov 28 '16 12:11

Keith


People also ask

What is ConnectionMultiplexer .NET core?

The ConnectionMultiplexer is the main arbiter of the connection to Redis inside the CLR, your application should maintain a single instance of the ConnectionMultiplexer throughout its runtime. You can initialize the Multiplexer with either a connection string, or with a ConfigurationOptions object.

What is StackExchange Redis?

StackExchange. Redis is a high performance general purpose redis client for . NET languages (C#, etc.). It is the logical successor to BookSleeve, and is the client developed-by (and used-by) Stack Exchange for busy sites like Stack Overflow.

What is Redis connection string?

Redis Connection strings have been expanded to support the more versatile URI format which is now able to capture most of Redis Client settings in a single connection string (akin to DB Connection strings).

What is lazy ConnectionMultiplexer?

It uses Lazy<T> to handle thread-safe initialization. It sets "abortConnect=false", which means if the initial connect attempt fails, the ConnectionMultiplexer will silently retry in the background rather than throw an exception.


1 Answers

What is the load expected to the app ? If you have much concurrency, I think using AddScoped would mean a lot of unnecessary burden to initiate and close connections for every request.

Also these observations IMHO show that you should use AddSingleton

(...) it is exceptionally rare that you would want to use a ConnectionMultiplexer briefly, as the idea is to re-use this object.

Another common use of redis is as a pub/sub message distribution tool; this is also simple, and in the event of connection failure, the ConnectionMultiplexer will handle all the details of re-subscribing to the requested channels.

Also, you will save memory having only one instance of ConnectionMultiplexer (IMHO).

like image 172
Niloct Avatar answered Sep 20 '22 09:09

Niloct