2017-10-18 62 views
12

W ASP.NET Core 2 możemy dodać Azure Redis Cache tak:ASP.NET Core 2 - Wiele usług Cache Azure Redis DI

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

Następnie użycie będzie tak:

private readonly IDistributedCache _cache; 

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

Jak mogę to zrobić tak, że będę mieć:

private readonly IDistributedCache _cache1; 
private readonly IDistributedCache _cache2; 

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

Moje pytania w jaki sposób mogę dodać kolejny serwis, który wskazuje na inny Azure Redis Cache Połączenie i instancja i rozdzielenie ich, gdy chcę z nich korzystać?

+0

Takie zaawansowane scenariusze są naprawdę nie do opanowania z domyślnego 'podejście IDistributedCache'. Powinieneś użyć biblioteki takiej jak [CacheManager] (http://cachemanager.michaco.net/), która pozwala ci definiować różne pamięci podręczne na podstawie argumentów typu. –

+2

Potencjalną opcją jest użycie [Wzorca strategii] (https://stackoverflow.com/a/46597099) w celu wybrania pamięci podręcznej do użycia w środowisku wykonawczym. – NightOwl888

Odpowiedz

8

Za scenę, AddDistributedRedisCache() metoda rozszerzenie ma następujące (code on github):

  1. Rejestry działanie, aby skonfigurować RedisCacheOptions. Lambda, którą przekazałeś do AddDistributedRedisCache() jest za to odpowiedzialna. Instancja z RedisCacheOptions jest przekazywana do konstruktora RedisCache zawiniętego w IOptions<T>.
  2. Rejestry Singletone implementacja RedisCache interfejsu IDistributedCache.

Niestety, oba te działania nie są dobrze dostosowane do tego, o co prosisz. Dla skonfigurowania określonego typu opcji można zarejestrować tylko jedną czynność. Natywna implementacja wtyczki zależności .net core does not support zastąpienie rejestracji.

Istnieje nadal rozwiązanie, które zrobi to, co chcesz. Jednak to rozwiązanie nieco mnie zabija.

Podstęp polega na tym, że dziedziczysz niestandardowe RedisCacheOptions1, RedisCacheOptions2 z RedisCacheOptions i rejestrujesz odrębne konfiguracje dla nich obu.

Następnie definiujesz własne interfejsy IDistributedCache1 i IDistributedCache2, które dziedziczą po IDistributedCache.

Na koniec definiujemy klasy RedisCache1 (dziedziczące implementację z RedisCache, a także implementujące IDistributedCache1) i RedisCache2 (to samo).

coś takiego:

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

Byłem na tej samej ścieżce co ty. Co masz na myśli przez: "jednak to rozwiązanie nieco mnie zabija"? Nie widzę niczego złego w tym podejściu i myślę, że zadziała dobrze – user2818430

+1

Mam na myśli to, że wymaga to znacznie więcej wysiłku niż powinno :( – CodeFuller