【问题标题】:Implementing caching of services in Domain project being used by a Web API在 Web API 使用的域项目中实现服务的缓存
【发布时间】:2014-05-14 20:01:17
【问题描述】:

我的问题是:如何在我的域项目中实现缓存,它的工作方式与使用存储库模式的普通堆栈一样。

我的设置如下所示:

  • ASP.NET MVC 网站
  • Web API
  • 域项目(使用 IoC,使用 Windsor)

例如,我的域项目有:

  • IOrderRepository.cs
  • OrderRepository.cs
  • Order.cs

我的 ASP.NET MVC 网站调用 Web API 并取回一些 DTO 类。然后,我的 Web API 将这些对象映射到我的域项目中的业务对象,并使应用程序工作。

我的应用程序中没有任何地方实现缓存。

应该在哪里实现缓存?

我考虑在 OrderRepository 的方法中执行此操作,因此我的 GetGetBySpecificationUpdate 方法必须调用由 OrderRepository 注入的一些通用缓存处理程序。

这显然给出了一些非常丑陋的代码,而且不是很通用。

如何维护缓存?

假设我们有一个像“OrderRepostory_123”这样的缓存键。当我调用 Update 方法时,我应该调用 cacheHandler.Delete("OrderRepository_123") 吗?因为那看起来也很丑

我自己的想法……

除了我描述的一些杂乱的方法之外,我真的看不出有什么好的方法。也许我可以做一些缓存层,但我想这意味着我的 WebAPI 不会再调用我的 OrderRepository,而是我的 CacheOrderRepository-something?

【问题讨论】:

  • 您需要全局缓存还是仅用于会话?您的存储库是在内存中还是使用数据库?性能是您使用缓存的主要动机吗?
  • 全局是我需要的缓存。存储库使用数据库。是的,表现是我目前唯一的动力。感谢您把这些事情说清楚!
  • 如果你碰巧在使用 EF,你可以在上面设置缓存
  • @Steve 我愿意,但这只会缓存在我的域 -> 数据库连接上。这不会解决 Web API -> 域项目之间的任何问题 :) 但这是一个有效且好的观点

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


【解决方案1】:

就个人而言,我不喜欢将缓存直接包含在存储库类中。一个类应该有一个改变的原因,而添加缓存通常会增加第二个原因。鉴于您的出发点,您至少有两个可能的合理选择:

  1. 创建一个新类,将缓存添加到存储库并公开相同的接口
  2. 创建一个使用一个或多个存储库并添加缓存的新服务接口

根据我的经验,#2 通常更有价值,因为您希望作为一个单元缓存的对象可能会跨存储库。当然,这取决于您如何确定存储库的范围。很大程度上可能取决于您的存储库是基于聚合根 (ala DDD)、表还是其他东西。

【讨论】:

    【解决方案2】:

    可能有上百万种不同的方法可以做到这一点,但在我看来(考虑到缓存的目的是提高性能)实现类似于存储库模式的缓存 - 域对象与缓存交互而不是数据库,那么也许后台线程可以使数据库和缓存保持同步,并且应用程序池的初始启动将填满缓存(假设需要急切加载)。大量的技术问题开始出现,例如如果缓存以违反数据库约束的方式被修改该怎么办。当任何与数据结构相关的问题可能需要在多个地方实现时,代码维护就成为一个问题。并发问题开始进入竞争。只是一些想法......

    【讨论】:

      【解决方案3】:

      SQLCacheDependency 与 System.Web.Caching.Cache,http://weblogs.asp.net/andrewrea/archive/2008/07/13/sqlcachedependency-i-think-it-is-absolutely-brilliant.aspx。这将使您的缓存因其他系统也应用更新而失效。

      【讨论】:

        【解决方案4】:

        根据情况有多个级别的缓存,但是如果您正在寻找具有少量更改的通用集中式缓存,我认为您将寻找 EF 二级缓存,有关更多详细信息,请查看以下http://msdn.microsoft.com/en-us/magazine/hh394143.aspx

        你也可以在 webapi 级别使用缓存

        如果 MVC 和 WebAPI 托管在 2 个不同的数据中心,请考虑网络流量

        对于大型读取访问门户,您可以考虑使用 Redis http://Redis.io

        【讨论】:

          【解决方案5】:

          听起来您想使用 .NET 缓存机制,而不是像 Redis 或 Memcache 这样的分布式缓存。我建议使用System.Runtime.Caching.MemoryCache 类而不是传统的System.Web.Caching.Cache 类。这样做允许您创建独立于 MVC/API 层的缓存层,因为 MemoryCache 不依赖于 System.Web。

          缓存您的 DTO 对象将大大加快您的应用程序的速度。这使您不必等待从镜像数据层的缓存中组装数据。例如,请求 Order123 只需要一次缓存读取,而不是多次读取任何 FK 数据。您的缓存层当然需要包含使您执行的更新时的缓存无效的逻辑。推荐的方法是检索缓存的订单对象并直接修改其属性,然后异步保存到数据库。

          【讨论】:

            猜你喜欢
            • 2015-07-18
            • 1970-01-01
            • 1970-01-01
            • 2016-12-06
            • 2013-02-14
            • 2022-01-25
            • 2018-06-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多