Loading

造轮子之缓存

缓存也是在业务开发过程中经常使用的一环。
在Asp.net core中,原生包含了MemoryCache内存缓存和DistributedCache分布式缓存两种缓存。
在Program中添加以下代码注册服务之后即可使用依赖注入使用两种缓存。

builder.Services.AddMemoryCache();

var redis = await ConnectionMultiplexer.ConnectAsync(builder.Configuration["Cache:Redis"]);
builder.Services.AddSingleton<IConnectionMultiplexer, ConnectionMultiplexer>(_ => redis);
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.ConnectionMultiplexerFactory = async () => await Task.FromResult(redis);
});

使用时只需要注入IMemoryCache或者IDistributedCache即可使用。
注意这里需要添加Microsoft.AspNetCore.DataProtection.StackExchangeRedis的nuget包。

扩展IDistributedCache

在原生使用中IDistributedCache不支持泛型GetSet,只能先序列化成字符串再操作。而IMemoryCache却可以,所以为了统一操作习惯,我们来扩展一下IDistributedCache。
添加一个DistributedCacheExtension类。

using System.Text.Json;

namespace Microsoft.Extensions.Caching.Distributed
{
    public static class DistributedCacheExtension
    {
        public static async Task<T> GetAsync<T>(this IDistributedCache cache, string key, CancellationToken cancellationToken = default)
        {
            var value = await cache.GetStringAsync(key, cancellationToken);
            if (string.IsNullOrWhiteSpace(value))
                return default(T);
            return JsonSerializer.Deserialize<T>(value);
        }
        public static async Task SetAsync<T>(this IDistributedCache cache, string key, T value, CancellationToken cancellationToken = default)
        {
            await cache.SetStringAsync(key, JsonSerializer.Serialize(value), cancellationToken);
        }
        public static async Task SetAsync<T>(this IDistributedCache cache, string key, T value, DistributedCacheEntryOptions distributedCacheEntryOptions, CancellationToken cancellationToken = default)
        {
            await cache.SetStringAsync(key, JsonSerializer.Serialize(value), distributedCacheEntryOptions, cancellationToken);
        }
        public static async Task SetAbsoluteExpirationRelativeToNowAsync<T>(this IDistributedCache cache, string key, T value, TimeSpan timeSpan, CancellationToken cancellationToken = default)
        {
            var options = new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = timeSpan
            };
            await cache.SetStringAsync(key, JsonSerializer.Serialize(value), options, cancellationToken);
        }
        public static async Task SetAbsoluteExpirationAsync<T>(this IDistributedCache cache, string key, T value, DateTimeOffset dateTimeOffset, CancellationToken cancellationToken = default)
        {
            var options = new DistributedCacheEntryOptions
            {
                AbsoluteExpiration = dateTimeOffset
            };
            await cache.SetStringAsync(key, JsonSerializer.Serialize(value), options, cancellationToken);
        }
        public static async Task SetSlidingExpirationAsync<T>(this IDistributedCache cache, string key, T value, TimeSpan slidingExpiration, CancellationToken cancellationToken = default)
        {
            var options = new DistributedCacheEntryOptions
            {
                SlidingExpiration = slidingExpiration
            };
            await cache.SetStringAsync(key, JsonSerializer.Serialize(value), options, cancellationToken);
        }
    }
}

这里我们使用System.Text.Json封装一下序列化的读写操作。顺带封装一下过期机制。
这里命名空间也使用Microsoft.Extensions.Caching.Distributed,这样我们就不需要再额外using命名空间才能使用这些扩展方法了。

轮子仓库地址https://github.com/Wheel-Framework/Wheel
欢迎进群催更。

image.png

posted @ 2023-10-08 16:50  饭勺oO  阅读(276)  评论(0编辑  收藏  举报