Mediatr - 使缓存无效/更新的正确位置在哪里
Posted
技术标签:
【中文标题】Mediatr - 使缓存无效/更新的正确位置在哪里【英文标题】:Mediatr - Where is the right place to invalidate/update cache 【发布时间】:2019-05-27 14:51:46 【问题描述】:这个问题源于我问过的关于太多接口、QCRS 和 Mediatr 库(请求/响应)的另一个问题
Mediatr: reducing number of DI'ed objects
我已经创建了一堆命令和查询,并且我有一堆行为,其中一个是缓存行为,对于每个查询,在实际对数据库执行查询之前检查缓存的值。到目前为止,这工作得很好,但是当我有一个 UpdateSomethingCommand 时会出现 delim,一旦我更新了数据库中的底层对象,我想用成功保存到数据库的内容来刷新缓存。
我的问题是具体何时真正更新缓存:
-
在 UpdateSomethingCommandHandler 中(这可能会破坏 SOLID 主体)
在 UpdateSomethingCommandHanlder 中调用另一个专门用于更新缓存的命令(不确定这是一个好的设计原则)
引入另一种专门用于更新缓存的行为(尚不知道如何处理)
有更好的解决方案吗?
【问题讨论】:
至于#2,不,你不应该这样做。看看这个页面的底部:jimmybogard.com/mediatr-9-0-released 【参考方案1】:我们对使用 MediatR 的项目也有类似的需求,最终将缓存合并到调解器管道中,包括您描述的缓存失效。
基本前提是我们在管道中插入了两种不同的行为,一种用于缓存来自请求的响应,另一种用于使缓存的来自不同请求的请求响应无效。
这两种行为之间存在一些相互作用,因为它们需要交换缓存密钥才能使正确的请求无效。
我最近将其中的一些工作放到了一个独立的库中,理论上可以将其按原样放入任何使用 MediatR 的项目中。在您的情况下,您可能只想查看我们在此处使用的技术并根据需要重新创建它们。
我不会在这里和现在重复所有内容,而是将您指向项目页面,在主页上的“入门”链接下有一些文档: https://github.com/Imprise/Imprise.MediatR.Extensions.Caching
在我看来,缓存失效使整个过程变得非常简单明了,但在某些情况下,我们需要更好地控制失效发生的时间。在这些情况下,我们采取的另一种方法是将ICache<TRequest, TResponse> cache
注入INotificationHandler
s,然后根据需要手动调用_cache.Remove(key);
。然后,从您知道应该使无效的任何请求中,只需提出由INotificationHandler
处理的通知,例如_mediator.Publish(SomethingUpdated);
【讨论】:
【参考方案2】:我的建议是使用一种缓存行为,该行为作用于实现某种 ICacheableRequest 标记接口的请求,并将缓存无效作为相应更新/删除命令处理程序中的一个步骤(就像您在第 1 点中提到的那样)。
如果您选择创建无效器行为,则会出现一些问题。
首先,不清楚该命令是否使缓存无效。每当我需要检查更新/删除实体时发生了什么时,我只需遵循命令处理程序,通过创建单独的缓存失效器没有副作用(更难遵循)。
其次,即使将失效代码放在单独的文件中更好地遵循 SRP,您也必须选择放置缓存失效器类的位置。它是在缓存查询旁边还是在使缓存无效的命令处理程序旁边?
第三,在许多情况下,您将没有足够的关于用于在关联命令中缓存请求的密钥的信息,您只能在 CommandHandler 中获得该信息以及任何其他额外的无效条件。
【讨论】:
以上是关于Mediatr - 使缓存无效/更新的正确位置在哪里的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Retrofit 和 OKHttp 在下一次请求时使缓存路由无效/强制更新?