1

How do I use multiple instances of redis in net core along with the DI container?

On startup I have the following:

services.AddStackExchangeRedisCache(options =>
{
     options.Configuration = distributedCacheConnectionString;
});

services.AddStackExchangeRedisCache(options =>
{
     options.Configuration = myAppSessionCacheConnectionString;
});

For injection I would have something like the following in a constructor for example:

namespace MyApp
{
    public class MyClass
    {
        public MyClass(IDistributedCache myAppSessionCache)
        {
            // use a specific redis cache instance here
            _distributedCache = myAppSessionCache;
        }
    }
}

namespace MyApp
{
    public class MyClass2
    {
        public MyClass2(IDistributedCache distributedCache)
        {
            // use a specific redis cache instance here
            _distributedCache = distributedCache;
        }
    }
}

I know for net core the DI container is limited compared something like Unity or Spring etc... I know for multiple implementations of an interface there are several tricks, one is injecting an IEnumerable of the interface, another example is typed interfaces, etc... I just don't see the option with the redis cache and we do have a need for an application to communicate with 2 separate redis servers within the system.

I am mostly looking for the path of least resistance. I can always create a wrapper around the Redis Client. I was just hoping that something existed but I was just overlooking it.

1 Answer 1

4

I think you need to be able to distinguish between two types of caches in your system (one for session and another for ordinary cache).

I think something like this can be done:

public interface ISessionDistributedCache : IDistributedCache {}

public interface IOrdinaryDistributedCache : IDistributedCache {}

then we have to implement these interfaces.

public class SessionDistributedCache : RedisCache, ISessionDistributedCache 
{
   public SessionDistributedCache(IOptions<RedisCacheOptions> optionsAccessor): base(optionsAccessor) {}
}

public class OrdinaryDistributedCache : RedisCache, IOrdinaryDistributedCache 
{
   public SessionDistributedCache(IOptions<RedisCacheOptions> optionsAccessor): base(optionsAccessor) {}
}

then in startup you can register these services like this:

services.AddSingleton<ISessionDistributedCache>(x =>
        {
            var options = x.GetRequiredService<IOptions<RedisCacheOptions>>();
            //options.Value.Configuration = ...  set you server IP, etc
            return new SessionDistributedCache(options);
        });
services.AddSingleton<IOrdinaryDistributedCache>(x =>
        {
            var options = x.GetRequiredService<IOptions<RedisCacheOptions>>();
            //options.Value.Configuration = ...  set you server IP, etc
            return new OrdinaryDistributedCache(options);
        });

Finally, you can use these two interfaces separately based on your needs.

Sign up to request clarification or add additional context in comments.

1 Comment

This does work and led me into the right direction, however I did have a slight different problem in that one service extension call is in a reusable standard library that we utilize. The other redis cache setup is specific to that application. Thank you, felt like a dummy afterwards...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.