You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 5 N-tier应用无需改动原有架构新增缓存层方案咨询

缓存层部署位置与架构设计方案

缓存层部署位置

缓存层放在业务层与数据库层之间是最优选择,完全不需要改动原有N层架构的核心结构、各层接口契约和业务逻辑代码。

调整后的调用链路为:

API layer
||
Business Layer
||
Cache Layer
||
Database Layer

缓存层对上游业务层完全透明,业务层无需感知缓存的存在,仅当缓存未命中时才会向下请求数据库层,查询完成后自动回写缓存再返回给上层。


无侵入实现方案

采用装饰器模式实现缓存层即可做到完全不改动原有架构逻辑:

  • 缓存层实现和原有数据库层完全一致的仓储/数据访问接口
  • 原有数据库层的实现作为缓存层的内部依赖传入
  • 依赖注入时仅修改注册逻辑,上层业务层的接口依赖无需任何调整

具体实现建议

  • 统一缓存键生成规则,推荐用{实体类型}:{参数特征值}的格式,比如Product:123,避免不同业务的缓存键冲突
  • 极少变更的数据可设置长周期的绝对过期时间,同时提供手动淘汰缓存的入口,数据变更时主动删除对应缓存即可避免脏数据
  • 本地部署场景直接用ASP.NET Core自带的IMemoryCache做内存缓存,分布式部署场景仅需修改缓存层的实现切换为分布式缓存,上层代码完全不需要调整
  • 缓存穿透、击穿、雪崩的常规防护要做:不存在的查询请求缓存空值,热点key加互斥锁,过期时间设置随机偏移量避免同时失效

实现示例

原有数据层代码(无需修改)

// 原有数据访问接口
public interface IProductRepository
{
    Task<Product> GetByIdAsync(int id);
}

// 原有数据库实现
public class ProductRepository : IProductRepository
{
    private readonly AppDbContext _dbContext;
    public ProductRepository(AppDbContext dbContext) => _dbContext = dbContext;

    public async Task<Product> GetByIdAsync(int id)
    {
        return await _dbContext.Products.FindAsync(id);
    }
}

新增缓存层代码

// 缓存装饰器,实现相同的数据访问接口
public class CachedProductRepository : IProductRepository
{
    private readonly IProductRepository _innerDatabaseRepo;
    private readonly IMemoryCache _cache;
    private const int CacheExpirationMinutes = 120;

    public CachedProductRepository(IProductRepository innerDatabaseRepo, IMemoryCache cache)
    {
        _innerDatabaseRepo = innerDatabaseRepo;
        _cache = cache;
    }

    public async Task<Product> GetByIdAsync(int id)
    {
        var cacheKey = $"Product:{id}";
        return await _cache.GetOrCreateAsync(cacheKey, async entry =>
        {
            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(CacheExpirationMinutes);
            return await _innerDatabaseRepo.GetByIdAsync(id);
        });
    }
}

依赖注入调整(仅需修改这一处注册逻辑)

// 原有注册逻辑注释即可
// services.AddScoped<IProductRepository, ProductRepository>();

// 新的注册逻辑
services.AddMemoryCache();
services.AddScoped<ProductRepository>();
services.AddScoped<IProductRepository, CachedProductRepository>(sp => 
{
    return new CachedProductRepository(
        sp.GetRequiredService<ProductRepository>(),
        sp.GetRequiredService<IMemoryCache>()
    );
});

内容的提问来源于stack exchange,提问作者Kerollos Melad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 00:24:04