ASP.NET 核心 2 - 多个 Azure Redis 缓存服务 DI

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

在 ASP.NET Core 2 中,我们可以像这样添加一个 Azure Redis 缓存:

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

那么用法是这样的:

private readonly IDistributedCache _cache;

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

我该怎么做才能拥有:

private readonly IDistributedCache _cache1;
private readonly IDistributedCache _cache2;

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

我的问题是如何添加另一个指向不同 Azure Redis 缓存连接和实例的服务,并在我想使用它们时将它们分开?

在幕后,AddDistributedRedisCache() 扩展方法执行以下操作 (code on github):

  1. 注册操作以配置 RedisCacheOptions。您传递给 AddDistributedRedisCache() 的 Lambda 对此负责。 RedisCacheOptions 的实例被传递给包装在 IOptions<T>.
  2. 中的 RedisCache 的构造函数
  3. 注册 IDistributedCache 接口的 RedisCache 单例实现。

不幸的是,这两种操作都不适合您的要求。 只能注册一个动作来配置特定类型的选项。 .net 核心依赖注入的本机实现 注册覆盖。

仍然有一个解决方案可以满足您的需求。但是这个解决方案有点让我难受。

诀窍是您从 RedisCacheOptions 继承自定义 RedisCacheOptions1、RedisCacheOptions2 并为它们注册不同的配置。

然后定义从 IDistributedCache 继承的自定义 IDistributedCache1 和 IDistributedCache2 接口。

最后定义 类 RedisCache1(它继承了 RedisCache 的实现并实现了 IDistributedCache1)和 RedisCache2(相同)。

像这样:

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>());