Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core 2 - Multiple Azure Redis Cache services DI

In ASP.NET Core 2 we can add a Azure Redis Cache like this:

 services.AddDistributedRedisCache(config =>
 {
    config.Configuration = Configuration.GetConnectionString("RedisCacheConnection");
    config.InstanceName = "MYINSTANCE";
 });

Then the usage will be like this:

private readonly IDistributedCache _cache;

public MyController(IDistributedCache cache)
{
   _cache = cache;
}

How can I do it so that I will have:

private readonly IDistributedCache _cache1;
private readonly IDistributedCache _cache2;

public MyController(IDistributedCache cache1, IDistributedCache cache2)
{
   _cache1 = cache1;
   _cache2 = cache2;
}

My questions how can I add another service that points to a different Azure Redis Cache Connection and instance and make separation of them when I want to use them?

like image 363
user2818430 Avatar asked Oct 18 '17 11:10

user2818430


1 Answers

Behind the scene, AddDistributedRedisCache() extension method does the following (code on github):

  1. Registers action to configure RedisCacheOptions. Lambda that you pass to AddDistributedRedisCache() is responsible for that. Instance of RedisCacheOptions is passed to constructor of RedisCache wrapped into IOptions<T>.
  2. Registers Singletone implementation RedisCache of IDistributedCache interface.

Unfortunatelly, both of these actions aren't well suited for what you ask. Only one action could be registered for configuring specific type of options. Native implementation of .net core dependency injection does not support registration override.

There is still a solution that will do what you want. However this solution somewhat killing me.

The trick is that you inherit your custom RedisCacheOptions1, RedisCacheOptions2 from RedisCacheOptions and register distinct configurations for both of them.

Then you define your custom IDistributedCache1 and IDistributedCache2 interfaces that inherit from IDistributedCache.

And finally you define classes RedisCache1 (that inherits implementation from RedisCache and also implements IDistributedCache1) and RedisCache2 (the same).

Something like this:

public interface IDistributedCache1 : IDistributedCache
{
}

public interface IDistributedCache2 : IDistributedCache
{
}

public class RedisCacheOptions1 : RedisCacheOptions
{
}

public class RedisCacheOptions2 : RedisCacheOptions
{
}

public class RedisCache1 : RedisCache, IDistributedCache1
{
    public RedisCache1(IOptions<RedisCacheOptions1> optionsAccessor) : base(optionsAccessor)
    {
    }
}

public class RedisCache2 : RedisCache, IDistributedCache2
{
    public RedisCache2(IOptions<RedisCacheOptions2> optionsAccessor) : base(optionsAccessor)
    {
    }
}

public class MyController : Controller
{
    private readonly IDistributedCache _cache1;
    private readonly IDistributedCache _cache2;

    public MyController(IDistributedCache1 cache1, IDistributedCache2 cache2)
    {
        _cache1 = cache1;
        _cache2 = cache2;
    }
}

//  Bootstrapping

services.AddOptions();

services.Configure<RedisCacheOptions1>(config =>
{
    config.Configuration = Configuration.GetConnectionString("RedisCacheConnection1");
    config.InstanceName = "MYINSTANCE1";
});
services.Configure<RedisCacheOptions2>(config =>
{
    config.Configuration = Configuration.GetConnectionString("RedisCacheConnection2");
    config.InstanceName = "MYINSTANCE2";
});

services.Add(ServiceDescriptor.Singleton<IDistributedCache1, RedisCache1>());
services.Add(ServiceDescriptor.Singleton<IDistributedCache2, RedisCache2>());
like image 117
CodeFuller Avatar answered Sep 28 '22 19:09

CodeFuller