<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      一般緩存采用redis緩存,當(dāng)然也存在沒有redis的情況,所以備用方案是memory緩存。

      但是使用的時(shí)候要進(jìn)行統(tǒng)一的注入,起碼要保證兩者繼承的接口是一致的

      需要用到的包

      Microsoft.Extensions.Caching.StackExchangeRedis

       

      1. 建立緩存的 接口和實(shí)現(xiàn)。CacheService和ICacheService,用于注入的時(shí)候使用

      接口比較簡(jiǎn)單,包括常用的 添加,刪除,清空,獲取,判斷是否存在,采用異步方式,異步好一些

          public interface ICacheService
          {
              Task SetAsync(string key, object value, TimeSpan? expirationTime = null);
              Task GetAsync(string key);
              Task RemoveAsync(string key);
              Task<bool> ExistAsync(string key);
              Task ClearAsync();
          }

       

      2.分別建立redis和memory 實(shí)現(xiàn)接口ICacheService

      redis 實(shí)現(xiàn)如下

          public class RedisCacheService(IConnectionMultiplexer connection) : ICacheService
          {
              private readonly IConnectionMultiplexer connection = connection;
              private readonly IDatabase redis = connection.GetDatabase();
      
              public async Task ClearAsync()
              {
                  var endpoints = connection.GetEndPoints();
                  var tasks = endpoints.Select(async x =>
                  {
                      var server = connection.GetServer(x);
                      foreach (var key in server.Keys())
                      {
                          await redis.KeyDeleteAsync(key);
                      }
                  });
      
                  await Task.WhenAll(tasks);
              }
      
              public async Task<bool> ExistAsync(string key)
              {
                  return await redis.KeyExistsAsync(key);
              }
      
              public async Task<string> GetAsync(string key)
              {
                  return await redis.StringGetAsync(key);
              }
      
              public async Task RemoveAsync(string key)
              {
                  await redis.KeyDeleteAsync(key);
              }
      
              public async Task SetAsync(string key, object value, TimeSpan? expirationTime = null)
              {
                  if (value != null)
                  {
                      //默認(rèn)2H
                      expirationTime ??= TimeSpan.FromHours(2);
                      if (value is string cacheStr)
                      {
                          await redis.StringSetAsync(key, cacheStr, expirationTime);
                      }
                      else
                      {
                          await redis.StringSetAsync(key, JsonSerializer.Serialize(value), expirationTime);
                      }
                  }
              }
          }

      memory 實(shí)現(xiàn)如下: 需要注意下,memory沒有清空的操作,可能有些大佬封裝的好一些,目前我這里沒有添加,但是我項(xiàng)目里是通過hashset來存儲(chǔ)鍵的,拆出來的時(shí)候圖省事直接不寫了,不是很影響,強(qiáng)迫癥例外

          public class MemoryCacheService(IMemoryCache memory) : ICacheService
          {
              private readonly IMemoryCache memory = memory;
      
              public Task ClearAsync()
              {
      

              return Task.CompletedTask;

              }
      
              public Task<bool> ExistAsync(string key)
              {
                  var exists = memory.TryGetValue(key, out _);
                  return Task.FromResult(exists);
              }
      
              public Task<string> GetAsync(string key)
              {
                  if (memory.TryGetValue(key, out string value))
                  {
                      return Task.FromResult(value);
                  }
      
                  return Task.FromResult<string>(null);
              }
      
              public Task RemoveAsync(string key)
              {
                  memory.Remove(key);
                  return Task.CompletedTask;
              }
      
              public Task SetAsync(string key, object value, TimeSpan? expirationTime = null)
              {
                  if (value != null)
                  {
                      //默認(rèn)2H
                      expirationTime ??= TimeSpan.FromHours(2);
                      if (value is string cacheStr)
                      {
                          memory.Set(key, cacheStr, expirationTime.Value);
                      }
                      else
                      {
                          memory.Set(key, JsonSerializer.Serialize(value), expirationTime.Value);
                      }
                  }
                  return Task.CompletedTask;
              }
          }

      3. 這一步比較重要,只是添加一種緩存那確實(shí)沒啥問題,我要的效果是,哪天redis掛了,項(xiàng)目會(huì)默認(rèn)使用memory,但是這對(duì)于開發(fā)來說,他無需在乎你掛沒掛,使用習(xí)慣仍然是一樣的,而不是要注入兩者不同的接口。就是體現(xiàn)在CacheService里面。類似于工廠類,注入之后會(huì)判斷下redis有沒有連接,連接了用redis,沒連接用memory。原理較為簡(jiǎn)單

      public class CacheService : ICacheService
      {
          private readonly ICacheService cache;
      
          public CacheService(IConnectionMultiplexer connection, IMemoryCache memory)
          {
              if (connection.IsConnected)
              {
                  cache = new RedisCacheService(connection);
              }
              else
              {
                  cache = new MemoryCacheService(memory);
              }
          }
      
          public async Task ClearAsync()
          {
              await cache.ClearAsync();
          }
      
          public async Task<bool> ExistAsync(string key)
          {
              return await cache.ExistAsync(key);
          }
      
          public async Task<string> GetAsync(string key)
          {
              return await cache.GetAsync(key);
          }
      
          public async Task RemoveAsync(string key)
          {
              await cache.RemoveAsync(key);
          }
      
          public async Task SetAsync(string key, object value, TimeSpan? expirationTime = null)
          {
              await cache.SetAsync(key, value, expirationTime);
          }
      }

      4.如何注入:redis配置主要是通過配置文件讀取,格式如下,未啟用或連接有問題時(shí),則開啟memory緩存。 redis瞬時(shí)注入,因?yàn)閿?shù)據(jù)在redis里共享,memory是整個(gè)程序的內(nèi)存,單例好些

        "Redis": {
          "Enable": false,
          "UseCluster": false,
          "ConnectionSingle": "127.0.0.1:6379",
          "ConnectionCluster": "node1:6379,node2:6379,node3:6379",
          "InstanceName": ""
        }
              public static void AddCacheSetup(this IServiceCollection services)
              {
                  if (AppSettings.AppString("Redis:Enable").ToBool())
                  {
                      var redisConfig = string.Empty;
      
                      if (AppSettings.AppString("Redis:UseCluster").ToBool())
                      {
                          redisConfig = AppSettings.AppString("Redis:ConnectionCluster");
                      }
                      else
                      {
                          redisConfig = AppSettings.AppString("Redis:ConnectionSingle");
                      }
      
                      var configurationOptions = ConfigurationOptions.Parse(redisConfig);
                      configurationOptions.ResolveDns = true;
      
                      try
                      {
                          var connectionMultiplexer = ConnectionMultiplexer.Connect(configurationOptions);
      
                          services.AddStackExchangeRedisCache(x =>
                          {
                              x.ConnectionMultiplexerFactory = () => Task.FromResult(connectionMultiplexer as IConnectionMultiplexer);
                              var instanceName = AppSettings.AppString("Redis:InstanceName");
                              if (!string.IsNullOrEmpty(instanceName))
                              {
                                  x.InstanceName = instanceName;
                              }
                          });
      
                          services.AddTransient<ICacheService, RedisCacheService>();
                      }
                      catch (Exception)
                      {
                          services.AddMemoryCache();
                          services.AddSingleton<ICacheService, MemoryCacheService>();
                      }
                  }
                  else
                  {
                      services.AddMemoryCache();
                      services.AddSingleton<ICacheService, MemoryCacheService>();
                  }
              }

      最后Program里:     builder.Services.AddCacheSetup();

      只需要在使用的地方注入ICacheService,就可以使用了,而不用在意用的是redis緩存還是memory緩存

      posted on 2025-01-10 16:38  嘗嘗手指  閱讀(151)  評(píng)論(0)    收藏  舉報(bào)

      主站蜘蛛池模板: 精品久久久久无码| 亚洲天堂视频网| 驻马店市| 久久精品一区二区东京热| 麻豆一区二区中文字幕| 国产精品久久久久久无毒不卡| 成年午夜无码av片在线观看| 成熟熟女国产精品一区二区| 91人妻熟妇在线视频| 国产成人av一区二区三区不卡| 中文字幕国产精品一区二| 亚洲综合精品第一页| 国产一区二区不卡自拍| 4480yy亚洲午夜私人影院剧情| 国产乱人伦AV在线麻豆A| 久久久久香蕉国产线看观看伊| 久热久精久品这里在线观看| 亚洲色成人一区二区三区| 亚洲日韩乱码一区二区三区四区 | 国产精成人品日日拍夜夜| 亚洲一区二区中文字幕| 最新亚洲春色av无码专区| 亚洲精品一区二区三区婷婷月| 国产伦码精品一区二区| 贵州省| 亚洲熟女一区二区av| 欧美老熟妇乱子伦牲交视频| 随州市| 爆乳日韩尤物无码一区| 亚洲区综合区小说区激情区| 亚洲国产区男人本色vr| 国内极度色诱视频网站| 茄子视频国产在线观看| 国产成人亚洲综合91精品| 亚洲国产精品久久久天堂麻豆宅男 | 甘南县| 国产精品黄色精品黄色大片| 天堂影院一区二区三区四区| 平遥县| 欧美色丁香| 人妻丝袜无码专区视频网站|