发现ABP——使用Redis

  Redis是项目中普遍使用到的缓存组件,在Abp中如何使用呢!

  首先先大概的看下abp源码结构:

  

 

从结构就能看出abp使用了StackExchange.Redis,展开包可看出其实它是引用的Microsoft.Extensions.Caching.StackExchangeRedis

还发现这里面还有UnitOfWork,还有待研究~~

 

系统中如何使用呢?

1、添加abp的包引用

可以通过cli命令添加:abp add-package Volo.Abp.Caching.StackExchangeRedis(注意要在使用缓存的项目中执行命令,在此为Application层,可自动向Module类添加DependsOn引用),

也可手动通过nuget包添加引用(添加引用后要在对应的Module类中手动添加DependsOn引用),效果如下:

 1 namespace abcFlow.WorkFlowEngine
 2 {
 3     [DependsOn(
 4         typeof(WorkFlowEngineDomainModule),
 5         typeof(WorkFlowEngineApplicationContractsModule),
 6         typeof(AbpDddApplicationModule),
 7         typeof(AbpAutoMapperModule)
 8         )]
 9     [DependsOn(typeof(AbpCachingStackExchangeRedisModule))]
10     public class WorkFlowEngineApplicationModule : AbpModule
11     {
12         public override void ConfigureServices(ServiceConfigurationContext context)
13         {
14             context.Services.AddAutoMapperObjectMapper<WorkFlowEngineApplicationModule>();
15             Configure<AbpAutoMapperOptions>(options =>
16             {
17                 options.AddMaps<WorkFlowEngineApplicationModule>(validate: true);
18             });
19 
20 
21             Configure<AbpDistributedCacheOptions>(options =>
22             {
23                 options.KeyPrefix = "demo";
24                 options.HideErrors = false;
25             });
26         }
27     }
28 }

代码中也添加了对AbpDistributedCacheOptions的配置,分别对应缓存前缀以及是否要隐藏错误(默认为true,在此为实验目的设为false);

2、设置redis连接属性

abp同样提供了appsettings.json文件配置以及在Module中通过ConfigureServices方法中配置,在此以appsettings.json为例:

1   "Redis": {
2     "IsEnabled": "true",
3     "Configuration": "127.0.0.1"
4   }

配置显示声明启用Redis并设置IP地址,本机端口号默认、无密码,该配置与StackExchangeRedis是一致的,可以进行验证下,包含集群模式也可以进行验证,问题不大。

 

以上就将Redis的配置设置好了,下面看下如何进行数据的读写:

3、Redis的数据读写

数据的读写放在Application层,调用方式如下:

 1 using JetBrains.Annotations;
 2 using System;
 3 using System.Threading.Tasks;
 4 using Volo.Abp;
 5 using Volo.Abp.Caching;
 6 
 7 namespace abcFlow.WorkFlowEngine.FlowDesign
 8 {
 9     public class WfSchemeAppService : WorkFlowEngineAppService, IWfSchemeAppService
10     {
11         private readonly IWfSchemeRepository _wfSchemeRepository;
12         private readonly IDistributedCache<WfSchemeDto> _distributedCache;
13 
14         public WfSchemeAppService(
15             IWfSchemeRepository wfSchemeRepository,
16             IDistributedCache<WfSchemeDto> distributedCache)
17         {
18             this._wfSchemeRepository = wfSchemeRepository;
19             this._distributedCache = distributedCache;
20         }
21 
22         public async Task<WfSchemeDto> FindAsync([NotNull] Guid id)
23         {
24             Check.NotNull(id, nameof(id));
25             return await _distributedCache.GetOrAddAsync(
26                 id.ToString(),
27                 async () => await GetWfSchemeById(id),
28                 () => new Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions
29                 {
30                     AbsoluteExpiration = DateTimeOffset.Now.AddHours(2)
31                 });
32         }
33 
34         private async Task<WfSchemeDto> GetWfSchemeById(Guid id)
35         {
36             var obj = await _wfSchemeRepository.FindAsync(id);
37             return ObjectMapper.Map<WfScheme, WfSchemeDto>(obj);
38         }
39     }
40 }
  • 首先进行注入IDistributedCache,在此指定了缓存的数据类型
  • 通过方法_distributedCache.GetOrAddAsync来实现缓存数据的读写(无数据时先加载数据再插入缓存),还可进行过期时间设置(在此可将时间提出出来作为常量)

看下Redis中存储的对象:

 

最后看下GetOrAddAsync的代码:

 1         /// <summary>
 2         /// Gets or Adds a cache item with the given key. If no cache item is found for the given key then adds a cache item
 3         /// provided by <paramref name="factory" /> delegate and returns the provided cache item.
 4         /// </summary>
 5         /// <param name="key">The key of cached item to be retrieved from the cache.</param>
 6         /// <param name="factory">The factory delegate is used to provide the cache item when no cache item is found for the given <paramref name="key" />.</param>
 7         /// <param name="optionsFactory">The cache options for the factory delegate.</param>
 8         /// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
 9         /// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
10         /// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
11         /// <returns>The cache item.</returns>
12         public virtual async Task<TCacheItem> GetOrAddAsync(
13             TCacheKey key,
14             Func<Task<TCacheItem>> factory,
15             Func<DistributedCacheEntryOptions> optionsFactory = null,
16             bool? hideErrors = null,
17             bool considerUow = false,
18             CancellationToken token = default)
19         {
20             token = CancellationTokenProvider.FallbackToProvider(token);
21             var value = await GetAsync(key, hideErrors, considerUow, token);
22             if (value != null)
23             {
24                 return value;
25             }
26 
27             using (await SyncSemaphore.LockAsync(token))
28             {
29                 value = await GetAsync(key, hideErrors, considerUow, token);
30                 if (value != null)
31                 {
32                     return value;
33                 }
34 
35                 value = await factory();
36 
37                 if (ShouldConsiderUow(considerUow))
38                 {
39                     var uowCache = GetUnitOfWorkCache();
40                     if (uowCache.TryGetValue(key, out var item))
41                     {
42                         item.SetValue(value);
43                     }
44                     else
45                     {
46                         uowCache.Add(key, new UnitOfWorkCacheItem<TCacheItem>(value));
47                     }
48                 }
49 
50                 await SetAsync(key, value, optionsFactory?.Invoke(), hideErrors, considerUow, token);
51             }
52 
53             return value;
54         }

 

From:发现ABP——使用Redis - 屈鲁奇 - 博客园 (cnblogs.com)

posted @ 2020-12-16 22:39  屈鲁奇  阅读(1814)  评论(0编辑  收藏  举报