缓存存储库,域或应用程序的问题?

时间:2011-08-10 10:25:38

标签: c# design-patterns domain-driven-design repository-pattern

我试图找出哪个层应该负责域驱动设计项目中的缓存(插入/删除)工作。目标是通过缓存从存储库中检索的任何实体来提高Web应用程序的性能。

我的解决方案如下分开:

MyApp.Infrastracture
MyApp.Repositories
MyApp.Domain
MyApp.WebApplication

我觉得因为它只是利用缓存的Web应用程序,所以缓存逻辑应该是这个层吗?然而,这并不正确,因为我希望保持Web应用程序的轻量级并专注于提供网页。

此外,缓存不是第一类域概念,因此在域层中不具有自然的适应性。

怎么办?

4 个答案:

答案 0 :(得分:11)

这是上述所有问题。

缓存是每个层需要单独处理并且应用程序需要协调的交叉问题之一。

答案 1 :(得分:5)

你注意到了

  

目标是通过缓存提高Web应用程序的性能   从存储库中检索的任何实体。

所以我认为你应该在你的资源库中透明地实现它。存储库旨在隐藏域中持久性的详细信息,如果要缓存大型对象以提高性能,那么域应该更加明智。您的存储库必须变得更加智能,可能跟踪同一对象的多个副本作为并行线程请求对象并同时改变它们。或者 - 如果可能的话 - 序列化对各个聚合根的访问,因为它们代表了事务边界。

正如@Oded指出的那样,缓存确实可以在任何地方发生,如果性能有问题,你很可能会发现自己在许多地方实现缓存,并且每个地点都可能采用不同的方式。例如,您可以在域中缓存某些查询的结果,也可以缓存整个HTML响应。

跨层协调的出现是因为缓存可能是一个非常漏洞的抽象。如果您的域对象被缓存,它们什么时候应该被缓存?如果一个线程使用缓存对象而另一个不使用缓存对象怎么办?如果您正在缓存查询结果,但基础对象已经改变了怎么办?从基础架构角度和业务角度来看,何时无效以及如何使无效是困难的问题。过时的查询并不总是坏事。

答案 2 :(得分:4)

我完全同意Oded这是一个跨领域的问题,但它对缓存项目的客户端也应该是透明的。

例如,存储库的用户不应关心项目是否被缓存。

我认为如果缓存是您解决方案的一个重要方面,那么它应该在域中明确说明,但是,您可能会发现它实际上最终作为基础架构的一部分并通过任何一个交付(静默)您使用的IoC容器。

答案 3 :(得分:0)

缓存可以分布在各层之间,如果你使用像Nhibernate这样支持多级缓存的ORM,有时可以在域层中自动实现缓存。在上层,它可以基于需求,例如在加载用户时,系统加载用户可以执行的功能,然后可以在应用程序级别缓存。所以这一切都取决于应用程序。