.NET 6控制台应用(仓储模式)本地JSON数据缓存实现方案问询
在.NET 6控制台应用中实现JSON数据缓存(结合仓储模式)
嘿,我之前在控制台应用里做过类似的缓存需求,其实思路和Web应用本质相通,只是控制台没有现成的Web宿主环境,需要我们手动搭建缓存的基础设施。下面给你两个贴合仓储模式的实用方案:
方案一:使用官方的IMemoryCache(推荐,符合.NET生态规范)
.NET的IMemoryCache并不是Web专属的,控制台应用也能通过依赖注入轻松集成,它支持缓存过期、大小限制、回调等高级特性,很适合仓储模式的架构。
步骤1:配置依赖注入与缓存服务
首先在控制台项目里,我们可以用HostBuilder来搭建一个轻量级的宿主环境,这样就能像Web应用一样使用DI和缓存服务:
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { // 注册内存缓存服务 services.AddMemoryCache(); // 注册你的仓储服务(结合缓存逻辑) services.AddScoped<IJsonDataRepository, JsonDataRepository>(); }) .Build(); // 获取仓储实例并使用 var repository = host.Services.GetRequiredService<IJsonDataRepository>(); var data = await repository.GetDataAsync(); // 后续调用直接从缓存取 var cachedData = await repository.GetDataAsync(); await host.RunAsync();
步骤2:在仓储中实现缓存逻辑
在你的仓储实现类中,注入IMemoryCache,然后在获取数据时先检查缓存,不存在则读取JSON并写入缓存:
using Microsoft.Extensions.Caching.Memory; using System.Text.Json; public interface IJsonDataRepository { Task<YourDataModel> GetDataAsync(); } public class JsonDataRepository : IJsonDataRepository { private readonly IMemoryCache _cache; private const string CacheKey = "LocalJsonData"; // 可以设置缓存过期时间(可选,比如1小时) private readonly MemoryCacheEntryOptions _cacheOptions = new() { AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1) }; public JsonDataRepository(IMemoryCache cache) { _cache = cache; } public async Task<YourDataModel> GetDataAsync() { // 先从缓存获取,不存在则执行后面的工厂方法 return await _cache.GetOrCreateAsync(CacheKey, async entry => { entry.SetOptions(_cacheOptions); // 读取本地JSON文件 var jsonContent = await File.ReadAllTextAsync("your-data.json"); return JsonSerializer.Deserialize<YourDataModel>(jsonContent); }); } }
GetOrCreateAsync方法自带线程安全机制,不用担心多个线程同时读取JSON文件的问题。
方案二:手动实现静态缓存(轻量简单场景)
如果你的应用很简单,不想引入DI和宿主环境,也可以用静态字段实现一个极简缓存,记得加上线程锁保证安全:
public class JsonDataRepository : IJsonDataRepository { private static YourDataModel _cachedData; private static readonly object _lockObj = new object(); public async Task<YourDataModel> GetDataAsync() { if (_cachedData != null) return _cachedData; lock (_lockObj) { // 双重检查锁,避免重复初始化 if (_cachedData != null) return _cachedData; var jsonContent = await File.ReadAllTextAsync("your-data.json"); _cachedData = JsonSerializer.Deserialize<YourDataModel>(jsonContent); return _cachedData; } } }
这个方案优点是轻量,不需要额外依赖,缺点是没有缓存过期、大小限制等高级特性,适合数据很少变动的场景。
注意事项
- 控制台应用的缓存是进程内的,只要程序不退出,缓存就会一直存在,完全符合你“首次运行缓存,后续直接获取”的需求。
- 如果JSON文件可能被外部修改,你可以考虑加上文件监听逻辑,当文件变化时清空缓存,下次获取时重新读取。
内容的提问来源于stack exchange,提问作者niler




