Redis Cache не может получить доступ к удаленному объекту - PullRequest
0 голосов
/ 24 января 2019

У меня есть основное приложение ASP.NET, и я пытаюсь использовать Redis Cache - однако я получаю сообщение об ошибке, в котором говорится, что не удается получить доступ к удаленному объекту, поэтому я не должен правильно настроить классы Cache.Я извлек классы обслуживания Cache в свой собственный репозиторий Nuget, чтобы его могли использовать другие приложения, передающие другой номер базы данных из appsettings.json в других приложениях

Я использую встроенный .NET Core DI для регистрациислужба кэширования, как показано ниже:

services.AddTransient<ICacheService, CacheService>();

Служба кэширования используется в моем Приложении, тогда как:

var dataFromCache = _cacheService.TryGetCachedObject<List<MyObject>>(cacheKey);

Значение моей службы кэширования в пакете nuget ниже:

public class CacheService : ICacheService, IDisposable

{
    public virtual T TryGetCachedObject<T>(string cacheKey)

    {

        if (RedisCacheHandler.Cache.KeyExists(cacheKey))

        {

            return JsonConvert.DeserializeObject<T>(RedisCacheHandler.Cache.StringGet(cacheKey));

        }

        return default(T);

    }
    //other metjhods omitted for brevity

Я получаю исключение невозможности доступа к удаленному объекту в строке if (RedisCacheHandler.Cache.KeyExists(cacheKey))

Мой класс обработчика кэша redis находится ниже (закомментированные строки, если что-то пыталось безуспешно.

public static class RedisCacheHandler

{

    private static Lazy<ConnectionMultiplexer> _lazyConnection;

    private static ConnectionMultiplexer Connection => _lazyConnection.Value;

    //private static CacheSettings _cacheSettings;



    public static IDatabase Cache { get; set; }



    //public static IDatabase Cache => Connection.GetDatabase(Convert.ToInt32(_cacheSettings.DbNumber));



    //private static readonly Lazy<ConnectionMultiplexer> LazyConnection

    //    = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(_cacheSettings.Connection));



    //public static ConnectionMultiplexer Connection => LazyConnection.Value;





    public static void AddRedisCacheHandler(this IServiceCollection services, IConfiguration configuration)

    {

        var cacheSettings = new CacheSettings();

        configuration.Bind("CacheSettings", cacheSettings);



        //_cacheSettings = cacheSettings;



        _lazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(cacheSettings.Connection));



        Cache = Connection.GetDatabase(Convert.ToInt32(cacheSettings.DbNumber));

    }

}

И я вызывал метод AddRedisCacheHandler в базовом классе запуска asp.net в методе ConfigureServices, как показано ниже:

services.AddRedisCacheHandler(Configuration);

EDIT

Использование этого метода заключается в том, что я нажимаю на контроллер API для получения справочных данных. Контроллер API вызывает сервисный уровень, который затем проверяет, находятся ли данные в кэше, и извлекает ихоттуда еще пойдет получить данные из БД и установить их в кеше на 24 часа

    private readonly IMyService _myService

    public MyController(IMyService myService)
    {
        _myService = myService;
    }

    [Route("SomeReferenceData")]
    public IEnumerable<SomeDto> GetReferenceData()
    {
        var data = _myService.GetRefData();
         //do stuff and return
    }

На сервисном уровне тогда код:

public class MyService : IMyService
{
    private readonly ICacheService _cacheService;
    private readonly CacheSettings _cacheSettings;    

    public MyService(CacheSettings cacheSettings, ICacheService cacheService)
    {
        _cacheSettings = cacheSettings;
        _cacheService = cacheService;
    }

    public virtual IEnumerable<MyObject> GetRefData()
    {

        string cacheKey = CachingConstants.CacheKey;

        var data = _cacheService.TryGetCachedObject<List<MyObject>>(cacheKey);

        if (data != null)
        {
            return data;
        }

        //go get data from db

        _cacheService.SetCachedObject<IEnumerable<MyObject>>(cacheKey, countries, Convert.ToInt32(_cacheSettings.DurationLongMinutes));

        return data;
    }

При запуске я звонюНиже перечислены все зависимости, включая службу кэширования:

services.RegisterServiceDependencies ();

public static class ServiceConfig
{
    public static void RegisterServiceDependencies(this IServiceCollection services)
    {
        services.AddTransient<ICacheService, CacheService>();
        //lots of other services

1 Ответ

0 голосов
/ 24 января 2019

Ты убиваешь себя здесь.Буквально ничего из этого не нужно.ASP.NET Core имеет встроенную поддержку распределенного кэширования, включая использование Redis в качестве поставщика.В вашем Startup.cs просто выполните:

services.AddDistributedRedisCache(options =>
{
    options.Configuration = "localhost";
    options.InstanceName = "SampleInstance";
});

Затем, когда вам нужно использовать кеш, просто введите IDistributedCache.Если вам нужен автономный способ автоматической сериализации / десериализации значений в кэше, вы можете просто добавить несколько методов расширения:

public static class IDistributedCacheExtensions
{
    public static async Task<T> GetAsync<T>(this IDistributedCache cache, string key) =>
        JsonConvert.DeserializeObject<T>(await cache.GetStringAsync(key));

    public static Task Set<T>(this IDistributedCache cache, string key, T value) =>
        cache.SetStringAsync(key, JsonConvert.SerializeObject(value));
}

Если вы настаиваете на наличии отдельного класса CacheService для этого, тогдапросто вставьте IDistributedCache в это, а затем сделайте свою работу там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...