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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM