ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

IMemoryCache内存缓存

2022-09-15 19:02:24  阅读:267  来源: 互联网

标签:缓存 typeResult cacheKey 内存 IMemoryCache using logger public


对于ASP.NET Core MVC 项目,框架会自动注入内存缓存服务。对于 ASP.NET Web API 等需要手动注入内存缓存服务。

注入内存缓存服务:

builder.Services.AddMemoryCache();//注入内存缓存服务

  内存缓存工具类接口:

using Microsoft.AspNetCore.Routing.Template;
using Microsoft.Extensions.Caching.Memory;

namespace TestWebApplication.Utility
{
    public interface IMemoryCacheHelper
    {
        TResult? GetOrCreate<TResult>(string cacheKey, Func<ICacheEntry, TResult?>
            valueFactory, int expireSeconds = 60);
        /// <summary>
        /// 从内存缓存中获取数据,没有则通过委托方法从数据库中获取并设置缓存
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="cacheKey">键</param>
        /// <param name="valueFactory">当缓存中不存在时,用此委托从数据库中获取</param>
        /// <param name="expireSeconds">多少秒后过期</param>
        /// <returns></returns>
        Task<TResult?> GetOrCreateAsync<TResult>(string cacheKey, Func<ICacheEntry, Task<TResult?>>
            valueFactory, int expireSeconds = 60);
        void Remove(string cacheKey);
    }
}

  实现:

using Microsoft.Extensions.Caching.Memory;

namespace TestWebApplication.Utility
{
    public class MemoryCacheHelper : IMemoryCacheHelper
    {
        private readonly IMemoryCache _cache;
        public MemoryCacheHelper(IMemoryCache cache)
        {
            _cache = cache;
        }
        private static void ValidateValueType<TResult>()
        {
            Type typeResult = typeof(TResult);
            if (typeResult.IsGenericType)//如果是泛型类型,获取泛型类型的定义
            {
                typeResult = typeResult.GetGenericTypeDefinition();
            }
            if (typeResult == typeof(IEnumerable<>) || typeResult == typeof(IEnumerable<TResult>)
                || typeResult == typeof(IAsyncEnumerable<TResult>)
                || typeResult == typeof(IQueryable<TResult>)
                || typeResult == typeof(IQueryable))
            {
                throw new InvalidOperationException($"please use List<T> or T[] instead.");
            }
        }
        private static void InitCacheEntry(ICacheEntry entry, int baseExpireSeconds)
        {
            double sec = Random.Shared.Next(baseExpireSeconds, baseExpireSeconds * 2);
            TimeSpan expiration = TimeSpan.FromSeconds(sec);
            entry.AbsoluteExpirationRelativeToNow = expiration;
        }
        public TResult? GetOrCreate<TResult>(string cacheKey, Func<ICacheEntry, TResult?> valueFactory, int expireSeconds = 60)
        {
            throw new NotImplementedException();
        }

        public async Task<TResult?> GetOrCreateAsync<TResult>(string cacheKey, Func<ICacheEntry, Task<TResult?>> valueFactory, int expireSeconds = 60)
        {
            ValidateValueType<TResult>();
            if (_cache.TryGetValue(cacheKey, out TResult? result)==false)
            {
                using ICacheEntry entry = _cache.CreateEntry(cacheKey);
                InitCacheEntry(entry, expireSeconds);
                result = await valueFactory(entry);
                entry.Value = result;
            }
            return result;
        }

        public void Remove(string cacheKey)
        {
            _cache.Remove(cacheKey);
        }
    }
}

  客户端使用

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using TestWebApplication.Utility;

namespace TestWebApplication
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesMemoryController : ControllerBase
    {
        private readonly ILogger<ValuesMemoryController> _logger;
        private readonly ApplicationDbContext _context;
        private readonly IMemoryCache _memoryCache;
        private readonly IMemoryCacheHelper _CacheHelper;
        public ValuesMemoryController(ILogger<ValuesMemoryController> logger, ApplicationDbContext context, IMemoryCache memoryCache, IMemoryCacheHelper cacheHelper)
        {
            _logger = logger;
            _context = context;
            _memoryCache = memoryCache;
            _CacheHelper = cacheHelper;
        }
        [HttpGet]
        public async Task<IEnumerable<PO>> GetPOs()
        {
            _logger.LogInformation($"开始执行{nameof(GetPOs)}:{DateTime.Now}");
            //var items = await _memoryCache.GetOrCreateAsync("AllPO", async (e) =>
            //{
            //    e.SlidingExpiration=TimeSpan.FromSeconds(10);
            //    e.AbsoluteExpirationRelativeToNow=TimeSpan.FromSeconds(30);
            //    _logger.LogInformation("从数据库中读取数据");
            //    return await _context.PO.Take(10).ToListAsync();
            //});
            var items = await _CacheHelper.GetOrCreateAsync("AllPO2", async (e) =>
            {
                _logger.LogInformation("从数据库中读取数据");
                return await _context.PO.Take(10).ToListAsync();
            }, 10);
            _logger.LogInformation("把数据返回给调用者");
            return items;
        }
    }
}

  

标签:缓存,typeResult,cacheKey,内存,IMemoryCache,using,logger,public
来源: https://www.cnblogs.com/friend/p/16697629.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有