发现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 }
作者:屈鲁奇
出处:https://www.cnblogs.com/quluqi
联系:496195435@qq.com QQ:496195435