将缓存添加到数据层(类库)中的mvc项目

时间:2017-11-03 22:53:01

标签: c# asp.net-mvc caching architecture

我有一个基于asp.net mvc的网站,由三层组成:

  1. 表示层(mvc网站)
  2. 域层(类库)
  3. 数据层(类库)
  4. 这是我的代码

    表示层:

    public ActionResult MyAction(int categoryId = 1)
        {
            var products = service.GetProductsByCategory(categoryId);
            return View(products );
        }
    

    域层:

    public List<MyProduct> GetProductsByCategory(int categoryId)
        {
            /* some code here */
            return myProductDao.GetProductsByCategory(categoryId);
        }
    

    数据层:

    public List<MyProduct> GetProductsByCategory(int categoryId)
        {
            /* check if data available in cache to avoid pulling database */
            using (var context = new myDbEntities())
            {
                var myproducts = context.ProductEntities.Where(p => p.CategoryId == categoryId);
                return Mapper.Map<List<ProductEntity>, List<Product>>(products);
            }
        }
    

    我们假设产品表每天只更改一次,我想添加一个缓存层以避免在特定时间内拉出数据库。

    问题: 我通常在控制器中使用HttpContext.Cache.Insert()进行缓存,但现在我计划将缓存添加到数据层,它是一个类库,没有HttpContext。通常如何在数据层中完成缓存

2 个答案:

答案 0 :(得分:2)

有很多方法可以解决这个问题。我要做的是抽象如何缓存一个接口,然后注入你想要缓存到数据层(包括使用HttpContext.Cache.Insert)。

MyProject.Cache

@objc func ATap(sender: UITapGestureRecognizer)
{
    let location = sender.location(in: self.SAView)
    // You need to Scale Location if your CAShapeLayers are Scaled

    for path in SAView.Paths
    {
        let value = path.value

        value.contains(location)

        if value.contains(location)
        {
            for (index, layer) in SAView.layer.sublayers!.enumerated()
            {
               if layer.name == path.key
                {
                    // Do something when specific layer is Tapped
                }
            }
        }
    }
}

MyProject.Web

public ICache
{
  void Insert (string key, object value)
}

MyProject.Domain

internal WebCache : ICache
{
  public void Insert(string key, object value)
  {
    HttpContext.Cache.Insert(key, value);  
  }
}

public Controller
{
  private service = new service(new WebCache);
}

MyProject.Data(如果您只想在数据层中缓存)

public Service
{
  private readonly ICache _cache;
  private readonly MyProductDao _myProductDao;
  public Service(ICache cache;)
  {
    _cache = cache;
    _myProductDao = new MyProductDao(_cache);
  }

  public List<MyProduct> GetProductsByCategory(int categoryId)
  {
      /* some code here */
      return _myProductDao.GetProductsByCategory(categoryId);
  }
}

根据需要扩展public MyProductDao { private readonly ICache _cache; public MyProductDao(ICache cache) { _cache = cache; } public List<MyProduct> GetProductsByCategory(int categoryId) { /* check if data available in cache to avoid pulling database */ _cache.DoWhatever().... using (var context = new myDbEntities()) { var myproducts = context.ProductEntities.Where(p => p.CategoryId == categoryId); return Mapper.Map<List<ProductEntity>, List<Product>>(products); } } 并在ICache上实施。

答案 1 :(得分:0)

  

通常如何在数据层中完成缓存

我认为 应该在数据层完成。

在我看来,将缓存添加到数据层似乎违反了单一责任原则。您的数据层应该只负责一件事 - 从持久存储(即数据库)获取数据。

在代码中的某个位置,您需要执行此工作流程(或其某些变体):

  1. 检查项目X的缓存。
  2. 如果找到,请从缓存中获取该项目。
  3. 如果找不到,请从持久存储中获取该项目。
  4. 退回物品。
  5. 在我看来,与数据层分开的组件应该执行此工作流程。

    以这种方式看待它:一旦你在数据库持久层之前放置一个缓存,你不仅仅是从数据库中获取数据了。您从这个新组件获取数据,组件决定从哪里获取记录(缓存与DB)。