Dynamic Cache (OrchardCore.DynamicCache)
动态缓存(OrchardCore.DynamicCache)
Purpose
目的
Dynamic Cache allows you to cache sections of markup.
动态高速缓存允许您缓存标记的各个部分。
Each cached section of markup can contain other (child) cached sections of markup.
标记的每个缓存部分都可以包含标记的其他(子)缓存部分。
Cached sections can all have their own cache policies, which allows for finer configuration options than a page level cache would have.
缓存部分都可以拥有自己的缓存策略,这允许比页面级缓存更精细的配置选项。
Cached values are stored using the IDynamicCache
service.
使用IDynamicCache
服务存储缓存的值。
Its default implementation is based on IDistributedCache
which is itself based on IMemoryCache
.
它的默认实现基于IDistributedCache
,它本身基于IMemoryCache
。
Example:
例:
Layout (not cached)
布局(未缓存)
-
Section A
-
A部分
-
Section A1 (varies by role)
-
Section A2
-
-
Section B
-
B节
-
Section B1 (varies by query string)
-
Section B2
-
Rendering cached sections
渲染缓存的部分
When this page is rendered for the first time, all shapes will be evaluated. Any blocks of markup that have been identified as cachable will be stored in the IDynamicCache
service.
首次渲染此页面时,将评估所有形状。任何已标识为可缓存的标记块都将存储在“IDynamicCache”服务中。
On subsequent requests, if a cacheable section has already been cached (and the cache entry is still valid) then it won't be processed (Processing
event in
在后续请求中,如果已缓存可缓存部分(并且缓存条目仍然有效),则不会处理它(处理中的Processing
事件)
the ShapeMetadata
). The markup will be retrieved from the cache and returned as part of the response.
ShapeMetadata
)。标记将从缓存中检索并作为响应的一部分返回。
Invalidating cached sections
使缓存的部分无效
If a cached section is invalidated, the markup for the section will be regenerated on the next request, and then placed back into the cache for subsequent requests to take advantage of.
如果缓存的部分无效,则将在下一个请求上重新生成该部分的标记,然后将其放回缓存中以供后续请求利用。
-
If its children are still cached then their cached value will be used.
-
如果它的子节点仍然被缓存,那么将使用它们的缓存值。
-
Invalidating a block will also invalidate all parent blocks.
-
使块无效也将使所有父块无效。
For instance, if Section B2
is invalidated, Section B
will also be invalidated. When the Layout is rendered, the Section B
code will run
例如,如果Section B2
无效,Section B
也将失效。渲染Layout时,将运行Section B
代码
again, as will Section B2
, but the cached content of Section B1
will be reused.
再次,部分B2
,但'部分B1`的缓存内容将被重用。
Cached sections can define dependencies, which allows the cache to know when the cached value should be invalidated.
缓存部分可以定义依赖关系,这允许缓存知道何时应该使缓存的值无效。
For example- if a cache section includes the body of a content item, you may want to automatically invalidate this cache section whenever that content item changes.
例如,如果缓存部分包含内容项的主体,则可能希望每当该内容项发生更改时自动使此缓存部分无效。
You can do this by adding the dependencies contentitemid:{ContentItemId}
to the cache section.
您可以通过将依赖项“contentitemid:{ContentItemId}”添加到缓存部分来完成此操作。
Cached sections can also be configured with a sliding expiration window, an absolute expiration window, or both.
缓存部分还可以配置滑动到期窗口,绝对到期窗口或两者。
If no expiration window is provided, a default sliding window of one minute will be used.
如果未提供到期窗口,则将使用一分钟的默认滑动窗口。
If both types of expiration windows are supplied, the sliding policy will be used, up to the maximum absolute time allowed by the absolute expiration window.
如果提供了两种类型的到期窗口,则将使用滑动策略,直到绝对到期窗口允许的最大绝对时间。
Well-known Cache dependencies
众所周知的Cache依赖项
Here is a list of common cache dependency values that can be used to invalidate cache entries.
以下是可用于使缓存条目无效的公共缓存依赖项值列表。
| Dependency | Description |
|依赖性|说明|
| --------- | ----------- |
| --------- | -----------
| contentitemid:{ContentItemId}
| Invalidated when a content item described with its unique id ({ContentItemId}
) is Published, Unpublished or Removed. |
| contentitemid:{ContentItemId}
|使用其唯一ID({ContentItemId}
)描述的内容项是已发布,未发布或已删除时无效。 |
| alias:{Alias}
| Invalidated when a content item with a specific alias ({Alias}
) is Published, Unpublished or Removed. |
| alias:{Alias}
|具有特定别名(“{Alias}”)的内容项为已发布,未发布或已删除时无效。 |
You can create your own dependencies by calling RemoveTagAsync()
on ITagCache
in response to events.
您可以通过在ITagCache
上调用RemoveTagAsync()
来响应事件来创建自己的依赖项。
Varying cached sections (Contexts)
改变缓存部分(上下文)
You may have a cached section that needs to be varied depending on the context of the request.
您可能有一个缓存部分需要根据请求的上下文进行更改。
An example of this would be a header section that is included on every page on the site, but contains different markup for each user (e.g. a log in form, or the currently logged in user's username etc...').
这方面的一个示例是包含在网站上每个页面上的标题部分,但是每个用户包含不同的标记(例如登录表单,或者当前登录用户的用户名等......)。
You can do this by adding 'vary by' values (called contexts) to the cache policy of a cached section.
您可以通过将“vary by”值(称为上下文)添加到缓存节的缓存策略来执行此操作。
Adding a user
context to the header example given above would create a unique cache item for each user that logs in to your site
在上面给出的标题示例中添加“user”上下文将为登录到您站点的每个用户创建一个唯一的缓存项
Contexts are hierarchical. For instance if a shape varies by user
and user.roles
contexts, only the user
value will be used
上下文是分层的。例如,如果形状因user
和user.roles
上下文而异,则仅使用user
值
as it's more specialized than the user.roles
one.
因为它比user.roles
更专业。
Contexts can be parameterized, for instance query:age
will pick the age
value of the query string.
上下文可以参数化,例如query:age
将选择查询字符串的age
值。
Available Contexts
可用的上下文
| Context | Description |
|上下文|说明|
| --------- | ----------- |
| --------- | -----------
| features
| The list of enabled features. |
| features
|已启用功能的列表。 |
| features:{featureName}
| The specified feature name. |
| features:{featureName}
|指定的功能名称。 |
| query
| The list of querystring values. |
| query
|查询字符串值列表。 |
| query:{queryName}
| The specified query name value. |
| query:{queryName}
|指定的查询名称值。 |
| user
| The current user. |
| user
|当前用户。 |
| user.roles
| The roles of the current user. |
| user.roles
|当前用户的角色。 |
| route
| The current request path. |
| route
|当前的请求路径。 |
You can create your own Contexts by implementing ICacheContextProvider
.
您可以通过实现ICacheContextProvider
来创建自己的上下文。
Fallback Contexts
后备上下文
Sometimes you may want to vary by a known value that is not an available context.
有时您可能希望根据不是可用上下文的已知值进行更改。
For example: You may wish to cache all your blog posts so that you can quickly display lists of your posts throughout your site. If the cache ID for the cache block was blog-post
, you can use a known value as a context to vary the cache item for each blog post. In this case, you could use the Content Item ID as a context:
例如:您可能希望缓存所有博客帖子,以便您可以在整个网站中快速显示帖子列表。如果缓存块的缓存ID是“blog-post”,则可以使用已知值作为上下文来改变每个博客帖子的缓存项。在这种情况下,您可以使用内容项ID作为上下文:
{% cache "blog-post-summary", vary_by: Model.ContentItemId %}
<font color=#0099ff size=4 face="黑体">{%cache“blog-post-summary”,vary_by:Model.ContentItemId%}</font>
...
{% endcache %}
<font color=#0099ff size=4 face="黑体">{%endcache%}</font>
Usage
用法
Cached sections can be configured to encompass a shape, or they can be explicitly added to markup with the cache
liquid block, or the cache
razor tag helper:
缓存的部分可以配置为包含一个形状,或者可以使用cache
liquid块或cache
razor tag helper将它们显式添加到标记中:
Caching a shape
缓存形状
ShapeMetadata.Cache(string cacheId)
When called on a shape instances, marks the shape as being cached. Returns a CacheContext
object.
在形状实例上调用时,将形状标记为正在缓存。返回一个CacheContext
对象。
Example: myShape.Cache("myshape")
示例:myShape.Cache(“myshape”)
CacheContext members
CacheContext成员
| Method | Description |
|方法|说明|
| --------- | ----------- |
| --------- | -----------
| WithDuration(Timespan)
| Cache the shape for the specific amount of time. |
| WithDuration(Timespan)
|缓存形状特定的时间。 |
| WithSlidingExpiration(Timespan)
| Cache the shape for a specific amount of time with a sliding window. |
| WithSlidingExpiration(Timespan)
|使用滑动窗口缓存形状特定的时间。 |
| AddContext(params string[])
| Varies the cached content on the specified context values. |
| AddContext(params string [])
|改变指定上下文值的缓存内容。 |
| RemoveContext(string)
| Removes the specified context. |
| RemoveContext(string)
|删除指定的上下文。 |
| AddDependency(params string[])
| Defines the context values that will invalidate the cache entry. |
| AddDependency(params string [])
|定义将使高速缓存条目无效的上下文值。 |
| RemoveDependency(string)
| Removes the specified dependency. |
| RemoveDependency(string)
|删除指定的依赖项。 |
| AddTag(string)
| Adds a tag to the cache entry to that it can be invalidated by this tag value. |
| AddTag(string)
|将标记添加到缓存条目,使其可以通过此标记值无效。 |
| RemoveTag(string)
| Removes the specified tag. |
| RemoveTag(string)
|删除指定的标记。 |
Note
!注意
`AddDependency` differs from `AddContext` in that it doesn't store multiple values for each context,
but invalidates the cached shape content when the value of the context varies.
Internally they share the same implementation, as the physical cache key will contain the dependency context value.
Shape Tag Helper Attributes
形状标记助手属性
When using shape tag helpers, the following attributes can be used:
使用形状标记帮助程序时,可以使用以下属性:
| Razor Attribute | Liquid Attribute | Description | Required |
|剃刀属性|液体属性|说明|必需|
| --------- | ----------- | ----------- | ----------- |
| --------- | ----------- ----------- -----------
| cache-id
| cache_id
| The identifier of the cached shape. | Yes |
| cache-id
| cache_id
|缓存形状的标识符。 |是的|
| cache-context
| cache_context
| A set of space/comma-separated context values. | No |
| cache-context
| cache_context
|一组空格/逗号分隔的上下文值。 |没有|
| cache-dependency
| cache_dependency
| A set of space/comma-separated dependency values. | No |
| cache-dependency
| cache_dependency
|一组空格/逗号分隔的依赖项值。 |没有|
| cache-tag
| cache_tag
| A set of space/comma-separated tag values. | No |
| cache-tag
| cache_tag
|一组空格/逗号分隔的标记值。 |没有|
| cache-fixed-duration
| cache_expires_after
| The cache duration of the entry, e.g. "00:05:00" for 5 minutes. | No |
| cache-fixed-duration
| cache_expires_after
|条目的缓存持续时间,例如“00:05:00”持续5分钟。 |没有|
| cache-sliding-duration
| cache_expires_sliding
| The sliding cache duration of the entry, e.g. "00:05:00" for 5 minutes. | No |
| cache-sliding-duration
| cache_expires_sliding
|该条目的滑动缓存持续时间,例如, “00:05:00”持续5分钟。 |没有|
e.g.: to cache the menu shape in a liquid template, you would use this markup:
例如:要将菜单形状缓存在液体模板中,您可以使用此标记:
{% shape "menu", alias: "alias:main-menu", cache_id: "main-menu", cache_expires_after: "00:05:00", cache_tag: "alias:main-menu" %}
Liquid cache block
液体缓存块
The liquid cache
block can be used to cache sections of markup. cache
blocks can be nested.
液体“缓存”块可用于缓存标记部分。 cache
块可以嵌套。
Arguments
参数
| Liquid Attribute | Description | Required |
|液体属性|说明|必需|
| --------- | ----------- | ----------- |
| --------- | ----------- -----------
| id
| The identifier of the cached shape. | Yes (this is the default first argument- no need to explicitly specify the name of this argument) |
| id
|缓存形状的标识符。 |是(这是默认的第一个参数 - 无需显式指定此参数的名称)|
| contexts
| A set of space/comma-separated context values. | No |
| contexts
|一组空格/逗号分隔的上下文值。 |没有|
| dependencies
| A set of space/comma-separated dependency values. | No |
| dependencies
|一组空格/逗号分隔的依赖项值。 |没有|
| expires_after
| The cache duration of the entry, e.g. "00:05:00" for 5 minutes. | No |
| expires_after
|条目的缓存持续时间,例如“00:05:00”持续5分钟。 |没有|
| expires_sliding
| The sliding cache duration of the entry, e.g. "00:05:00" for 5 minutes. | No |
| expires_sliding
|该条目的滑动缓存持续时间,例如, “00:05:00”持续5分钟。 |没有|
Examples
例子
Simple block:
简单块:
{% cache "my-cache-block" %}
<font color=#0099ff size=4 face="黑体">{%cache“my-cache-block”%}</font>
...
{% endcache %}
<font color=#0099ff size=4 face="黑体">{%endcache%}</font>
Nested blocks:
嵌套块:
{% cache "a" %}
<font color=#0099ff size=4 face="黑体">{%cache“a”%}</font>
A {{ "now" | date: "%T" }} (No Duration) <br />
{% cache "a1", dependencies: "a1", vary_by: "user", expires_after: "0:5:0" %}
A1 {{ "now" | date: "%T" }} (5 Minutes) <br />
{% endcache %}
{% cache "a2", dependencies: "a2", expires_after: "0:0:1" %}
A2 {{ "now" | date: "%T" }} (1 Second) <br />
{% cache "a2a", dependencies: "a2a", contexts: "route", expires_sliding: "0:0:5" %}
A2A {{ "now" | date: "%T" }} (5 Seconds) <br />
{% endcache %}
{% endcache %}
{% endcache %}
<font color=#0099ff size=4 face="黑体">{%endcache%}</font>
Altering a cache scope
更改缓存范围
You may not yet know all the child dependencies, or even how long the cache block should be cached for when you enter a cache block.
您可能还不知道所有子依赖项,甚至还不知道在您输入缓存块时缓存块应该缓存多长时间。
An example might be a cache block around a list of content items from a query- because you do not know which content items will be displayed by the query, you cannot define the correct dependencies when you enter the cache block.
一个示例可能是来自查询的内容项列表周围的缓存块 - 因为您不知道查询将显示哪些内容项,所以在输入缓存块时无法定义正确的依赖项。
There are four tags that allow you to alter the current cache scope. It's safe to use these tags even if you don't necessarily know if you're inside a cache block:
有四个标记允许您更改当前缓存范围。即使您不一定知道自己是否在缓存块中,使用这些标记也是安全的:
| Liquid Tag | Description | Example |
|液体标签|说明|示例|
| --------- | ----------- | ----------- |
| --------- | ----------- -----------
| cache_dependency
| Adds a dependency to the current cache scope | {% cache_dependency "alias:{Alias}" %}
|
| cache_dependency
|向当前缓存范围添加依赖项| {%cache_dependency'别名:{Alias}“%}
|
| cache_expires_on
| Sets a fixed date and time that the cache item will expire. The most restrictive cache policy (i.e. the one with the shortest life) will win in the event of multiple expiry policies being defined for a single block. | {% cache_expires_on {A DateTime or DateTimeOffset instance %}
(e.g. from a date/time field on a content item) |
| cache_expires_on
|设置缓存项目将过期的固定日期和时间。如果为单个块定义了多个到期策略,则限制性最强的缓存策略(即具有最短寿命的缓存策略)将获胜。 | {%cache_expires_on {DateTime或DateTimeOffset instance%}
(例如来自内容项的日期/时间字段)|
| cache_expires_after
| Sets a timespan relative to when the item was cached that the cache item will expire. The most restrictive cache policy (i.e. the one with the shortest life) will win in the event of multiple expiry policies being defined for a single block. | {% cache_expires_after "01:00:00" %}
(One hour) |
| cache_expires_after
|设置相对于缓存项目缓存项目到期时的时间跨度。如果为单个块定义了多个到期策略,则限制性最强的缓存策略(即具有最短寿命的缓存策略)将获胜。 | {%cache_expires_after“01:00:00”%}
(一小时)|
| cache_expires_sliding
| Sets a sliding window for the expiry of the cache item. The most restrictive cache policy (i.e. the one with the shortest life) will win in the event of multiple expiry policies being defined for a single block. | {% cache_expires_sliding "00:01:00" %}
(One minute) |
| cache_expires_sliding
|为缓存项的到期设置滑动窗口。如果为单个块定义了多个到期策略,则限制性最强的缓存策略(即具有最短寿命的缓存策略)将获胜。 | {%cache_expires_sliding“00:01:00”%}
(一分钟)|
Example:
例:
Displaying content items from a query:
显示查询中的内容项:
{% cache "recent-blog-posts"}
<font color=#0099ff size=4 face="黑体">{%cache“recent-blog-posts”}</font>
{% assign recentBlogPosts = Queries.RecentBlogPosts | query %}
{% for item in recentBlogPosts %}
{{ item | display_text }}
<font color=#0099ff size=4 face="黑体"></font>
{% assign cacheDependency = "contentitemid:" | append: Model.ContentItem.ContentItemId %}
{% cache_dependency cacheDependency %}
{% endfor %}
{% endcache %}
<font color=#0099ff size=4 face="黑体">{%endcache%}</font>
Each item that is displayed by the query will now add its own cache dependency to the recent-blog-posts
cache block.
查询显示的每个项目现在都会将自己的缓存依赖项添加到recent-blog-posts
缓存块中。
Razor cache tag
剃刀缓存标签
This has not yet been implemented. If you feel up to it, and you'd like to help out, then please raise a pull request.
这尚未实施。如果您对此感到满意,并希望提供帮助,请提出拉取请求。