2017-11-03 129 views
1

我有一个asp.net基于MVC的网站,包括三个层次:添加缓存,在数据层MVC项目(类库)

  1. 表示层(MVC网站)
  2. 领域层(类库)
  3. 数据层(类库)

和这里是我的代码

PR esentation层:

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的。通常在数据层中缓存如何完成

+0

如果需要,您可以在数据层中添加对具有HttpContext的程序集的引用。但恕我直言,我个人不会将缓存添加到数据层。我会保持数据层,因此它总是从数据库中提取数据。我将保持控制器和数据访问层之间的缓存层(可能是业务层) – Shyju

+0

@Shyju剂量添加一个对具有HttpContext的程序集的引用,正确的方法是做什么? –

+0

呵呵,人不要添加引用,只需创建一个接口并将其作为依赖关系传递给它。发布答案。 –

回答

2

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

MyProject.Cache

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

MyProject.Web

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

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

MyProject.Domain

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); 
    } 
} 

MyProject.Data(如果你只是想在数据层高速缓存)

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并在您的internal WebCache上实现它。

0

如何通常数据层

做高速缓存,我不认为它应该数据层来完成。

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

在代码中的某个地方,你需要做这个工作流程(或者它的一些变体):

  1. 检查
  2. 如果发现缓存中的项目十,获得该项目从缓存中。
  3. 如果找不到,从持久存储中获取该项目。
  4. 退货此商品。

在我看来,一个独立于数据层的组件应该完成这个工作流程。

这样看待:一旦将缓存置于数据库持久层之前,您就不再只是从数据库获取数据。您从这个新组件获取数据,并且组件决定从哪里获取记录(缓存与数据库)。