• asp.net core上使用Redis探索(2)


    在<<asp.net core上使用Redis探索(1)>>中,我介绍了一个微软官方实现Microsoft.Extensions.Caching.Redis的类库,这次,我们使用微软官方的Redis客户端。

    使用Nuget引入Microsoft.Extensions.Caching.Redis库, 依赖项:
    Microsoft.Extensions.Caching.Abstract
    Microsoft.Extensions.Options
    StackExchange.Redis.StrongName

    原来Microsoft.Extensions.Caching.Redis其实就是封装了StackExchange.redis,作为.net core平台下的redis客户端与redis通信的。


    源码地址:
    https://github.com/aspnet/Caching/tree/dev/src/Microsoft.Extensions.Caching.Redis
    源码分析:
    RedisCache继承自IDistributeCache接口,该接口是Microsoft.Extensions.Caching.Distributed命名空间下的一个接口,主要就是封装了Redis的一些最基本的操作,比如,Set, Get, Refresh, Remove.就是最基本的增删改查。
    RedisCache类中有一个用于同步的SemaphoreSlim类,该类是CLR中的同步遍历的混合构造——内核模式和用户模式的混合。该类除了显式实现了IDistributedCache的所有方法外,还有一个重要的方法要说下,那就是Connect()方法:

     1 private void Connect()
     2 {
     3     if (_cache != null)
     4     {
     5         return;
     6     }
     7 
     8     _connectionLock.Wait();
     9     try
    10     {
    11         if (_cache == null)
    12         {
    13             _connection = ConnectionMultiplexer.Connect(_options.Configuration);
    14             _cache = _connection.GetDatabase();
    15         }
    16     }
    17     finally
    18     {
    19         _connectionLock.Release();
    20     }
    21 }

    该方法用于连接Redis服务器,通过RedisCacheOptions这个类的属性,来连接redis数据库,源码:

     1 /// <summary>
     2 /// Configuration options for <see cref="RedisCache"/>.
     3 /// </summary>
     4 public class RedisCacheOptions : IOptions<RedisCacheOptions>
     5 {
     6     /// <summary>
     7     /// The configuration used to connect to Redis.
     8     /// </summary>
     9     public string Configuration { get; set; }
    10 
    11     /// <summary>
    12     /// The Redis instance name.
    13     /// </summary>
    14     public string InstanceName { get; set; }
    15 
    16     RedisCacheOptions IOptions<RedisCacheOptions>.Value
    17     {
    18         get { return this; }
    19     }
    20 }

    其中的Configuration属性就是我们的一般在.config文件中配置redis连接语句的地方,随后我们会讲到应用。而InstanceName是什么?继续看源码(RedisCache.cs文件):

    private readonly RedisCacheOptions _options;
    public RedisCache(IOptions<RedisCacheOptions> optionsAccessor)
    {
        if (optionsAccessor == null)
        {
            throw new ArgumentNullException(nameof(optionsAccessor));
        }
    
        _options = optionsAccessor.Value;
    
        // This allows partitioning a single backend cache for use with multiple apps/services.
        _instance = _options.InstanceName ?? string.Empty;
    }

    可以看到,这个属性是可以设置为空的,那么它到底是什么呢?这个就是我们在存储redis的时候的前缀了,我们可以这么这是Demo, 或者Demo:test等。
    也就是说RedisCache类主要就是实现了IDistributedCache接口的所有方法,同时另外实现了Connect()方法用来连接redis,而这个的连接又是基于StackExchange.Redis(关于StackExchange.Redis请看  StackExchange.Redis通用封装类分享 )的ConnectionMultiplexer。但是我们在大型项目中使用的redis队列在RedisCache类中并没有实现,但是,要知道整个asp.net-core都是可拓展的,我们可以基于RedisCache类再实现一个pub/sub方法用来做消息队列。
    最后使用asp.net-core默认的DI容器将RedisCache类注册到框架中。RedisCacheServiceCollectionExtensions类源码:

     1 /// <summary>
     2 /// Extension methods for setting up Redis distributed cache related services in an <see cref="IServiceCollection" />.
     3 /// </summary>
     4 public static class RedisCacheServiceCollectionExtensions
     5 {
     6     /// <summary>
     7     /// Adds Redis distributed caching services to the specified <see cref="IServiceCollection" />.
     8     /// </summary>
     9     /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
    10     /// <param name="setupAction">An <see cref="Action{RedisCacheOptions}"/> to configure the provided
    11     /// <see cref="RedisCacheOptions"/>.</param>
    12     /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
    13     public static IServiceCollection AddDistributedRedisCache(this IServiceCollection services, Action<RedisCacheOptions> setupAction)
    14     {
    15         if (services == null)
    16         {
    17             throw new ArgumentNullException(nameof(services));
    18         }
    19 
    20         if (setupAction == null)
    21         {
    22             throw new ArgumentNullException(nameof(setupAction));
    23         }
    24 
    25         services.AddOptions();
    26         services.Configure(setupAction);
    27         // .net core DI容器的使用无非就是在容器中实例化接口,而接口的的实例化,是通过实例化接口的派生类(即以接口为父类的子类)...
    28         services.Add(ServiceDescriptor.Singleton<IDistributedCache, RedisCache>());
    29 
    30         return services;
    31     }
    32 }

    在这里我们基于IServiceCollection接口拓展出来了一个方法,该方法就是微软官方为我们创建的基于Redis的实现了,在最后使用DI的三种方法的Singleton来实现IOC。那么我们怎么来使用呢?
    引入完了Microsoft.Extensions.Caching.Redis之后,在Startup类中:

    1 services.AddDistributedRedisCache(option =>
    2 {
    3     option.Configuration = "123.207.96.138:6379, password=*****";
    4     option.InstanceName = "";
    5 });

    个人的建议是给Redis设置一个密码,要不然容易被攻击。
    接下来就是给Redis设置值了, 我们新建一个WebApi的程序,然后新建一个HomeController Api控制器

     1 [Produces("application/json")]
     2 [Route("api/[controller]")]
     3 public class HomeController : Controller
     4 {
     5     // 通过构造函数注入,内置IOC容器实例化了之后,就可以通过接口对象来调用相应的函数了.
     6     private readonly IDistributedCache _distributedCache;
     7 
     8     public HomeController(IDistributedCache distributedCache)
     9     {
    10         _distributedCache = distributedCache;
    11     }
    12 
    13     [HttpGet]
    14     public async Task<string> Get()
    15     {
    16         
    17         var cacheKey = "TheTime";
    18 
    19         //await _distributedCache.RemoveAsync(cacheKey);
    20         
    21         var existingTime = _distributedCache.GetString(cacheKey);
    22         if (!string.IsNullOrEmpty(existingTime))
    23         {
    24             return "Fetched from cache : " + existingTime;
    25         }
    26         else
    27         {
    28             existingTime = DateTime.UtcNow.ToString();
    29             
    30             _distributedCache.SetString(cacheKey, existingTime);
    31             return "Added to cache : " + existingTime;
    32         }
    33     }
    34 }

    代码我就不运行了,亲测能用。

    百度云盘demo下载地址: 

    链接:https://pan.baidu.com/s/1vzuS5pEk_Ouh9I-NkPWXfg 密码:armw

  • 相关阅读:
    【EFCORE笔记】客户端与服务端求值&跟踪与非跟踪查询
    【EFCORE笔记】预先加载&显式加载&延迟加载
    【EFCORE笔记】在远程查询数据
    【EFCORE笔记】远程数据查询支持
    【EFCORE笔记】元素操作&集合运算&转换类型
    【EFCORE笔记】生成操作&相等比较&串联运算
    【EFCORE笔记】联接运算与数据分组
    【EFCORE笔记】投影运算与数据分区
    【EFCORE笔记】排序&集运算&筛选&限定
    【EFCORE笔记】团队环境中的迁移
  • 原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/8944200.html
Copyright © 2020-2023  润新知