You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

.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

火山引擎 最新活动