是否缓存存储库、域或应用程序关注点

本文关键字:应用程序 关注点 缓存 存储 是否 | 更新日期: 2023-09-27 18:05:10

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

我的解决方案分离如下:

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

我觉得既然只有Web应用程序使用缓存,那么缓存逻辑应该是这一层?然而,这感觉不正确,因为我想保持web应用程序轻量级和专注于服务网页。

缓存也不是一个一流的领域概念,所以不适合在领域层。

该怎么办?

是否缓存存储库、域或应用程序关注点

这是上述所有人都关心的问题。

缓存是横切关注点之一,每一层需要单独处理,应用程序需要编排。

您注意到了

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

所以我认为你应该在你的存储库中透明地实现它。存储库的目的是向域隐藏持久性的细节,如果您希望缓存大型对象以提高性能,那么域应该不会知道。您的存储库必须变得更加智能,可能会在并行线程请求对象时跟踪同一对象的多个副本,并同时更改它们。或者——如果可能的话——序列化对单个聚合根的访问,因为它们代表事务边界。

正如@Oded指出的那样,缓存实际上可以在任何地方发生,如果性能存在问题,您可能会发现自己在许多地方实现它,并且每个地方的做法可能不同。例如,您可能会在域中缓存某些查询的结果,或者缓存整个HTML响应。

跨层协调之所以出现,是因为缓存可能是一个相当有漏洞的抽象。如果您的域对象被缓存,那么何时应该取消缓存?如果一个线程正在使用缓存对象,而另一个线程没有,该怎么办?如果正在缓存查询结果,但底层对象后来发生了变化,该怎么办?无论从基础设施的角度还是从业务的角度来看,何时使其无效以及如何使其无效都是困难的问题。过时的查询并不总是不好的。

我完全同意Oded的观点,这是一个横切关注点,但它也应该对缓存项的客户端透明。

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

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

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