Orchardcms 如何为内容部分(如小部件)实现输出缓存?
我有一个小部件,上面有最近的新闻列表,如何只缓存小部件输出? OutputCache模块为匿名用户缓存整个页面,但实际上我只需要缓存一个形状输出。Orchardcms 如何为内容部分(如小部件)实现输出缓存?,orchardcms,Orchardcms,我有一个小部件,上面有最近的新闻列表,如何只缓存小部件输出? OutputCache模块为匿名用户缓存整个页面,但实际上我只需要缓存一个形状输出。 这里有什么解决方案 Orchard提供了一个名为CacheManager的服务,它既棒又酷,让缓存变得超级简单。文档中提到了它,但它并不是关于如何使用它的特别有用的描述()。查看示例的最佳位置是Orchard核心代码和第三方模块,如Favicon和twitter小部件(所有这些都是人们希望的) 幸运的是,其他善良的人已经开始努力为你搜索果园代码,并为
这里有什么解决方案 Orchard提供了一个名为CacheManager的服务,它既棒又酷,让缓存变得超级简单。文档中提到了它,但它并不是关于如何使用它的特别有用的描述()。查看示例的最佳位置是Orchard核心代码和第三方模块,如Favicon和twitter小部件(所有这些都是人们希望的)
幸运的是,其他善良的人已经开始努力为你搜索果园代码,并为此写一些漂亮的博客文章。最新Twitter小部件的开发人员写了一篇简洁的帖子:。NogginBox的Richard也是。当然,Bertrand也有一篇关于这个主题的有用文章:Orchard提供了一个名为CacheManager的服务,它非常棒,非常酷,并且使缓存变得非常简单。文档中提到了它,但它并不是关于如何使用它的特别有用的描述()。查看示例的最佳位置是Orchard核心代码和第三方模块,如Favicon和twitter小部件(所有这些都是人们希望的)
幸运的是,其他善良的人已经开始努力为你搜索果园代码,并为此写一些漂亮的博客文章。最新Twitter小部件的开发人员写了一篇简洁的帖子:。NogginBox的Richard也是。当然,Bertrand在这个主题上也有一篇有用的帖子:缓存
形状
对象本身不是一个好主意,但是您可以从形状
捕获HTML输出并缓存它
每个乌节形状
都有一个相应的对象,称为元数据
。除其他外,此对象包含一些事件处理程序,这些事件处理程序可以在显示形状时或显示后运行。通过使用这些事件处理程序,可以在第一次调用驱动程序时缓存形状的输出。然后,对于以后对驱动程序的调用,我们可以显示输出的缓存副本,而不是运行驱动程序或模板渲染的昂贵部分
例如:
using System.Web;
using DemoModule.Models;
using Orchard.Caching;
using Orchard.ContentManagement.Drivers;
using Orchard.DisplayManagement.Shapes;
namespace DemoModule.Drivers {
public class MyWidgetPartDriver : ContentPartDriver<MyWidgetPart> {
private readonly ICacheManager _cacheManager;
private readonly ISignals _signals;
public MyWidgetPartDriver(
ICacheManager cacheManager,
ISignals signals
) {
_cacheManager = cacheManager;
_signals = signals;
}
public class CachedOutput {
public IHtmlString Output { get; set; }
}
protected override DriverResult Display(MyWidgetPart part, string displayType, dynamic shapeHelper) {
return ContentShape("Parts_MyWidget", () => {
// The cache key. Build it using whatever is needed to differentiate the output.
var cacheKey = /* e.g. */ string.Format("MyWidget-{0}", part.Id);
// Standard Orchard cache manager. Notice we get this object by reference,
// so we can write to its field to save our cached HTML output.
var cachedOutput = _cacheManager.Get(cacheKey, ctx => {
// Use whatever signals are needed to invalidate the cache.
_signals.When(/* e.g. */ "ExpireCache");
return new CachedOutput();
});
dynamic shape;
if (cachedOutput.Output == null) {
// Output has not yet been cached, so we are going to build the shape normally
// and then cache the output.
/*
... Do normal (potentially expensive) things (call DBs, call services, etc.)
to prep shape ...
*/
// Create shape object.
shape = shapeHelper.Parts_MyWidget(/*...*/);
// Hook up an event handler such that after rendering the (potentially expensive)
// shape template, we capture the output to the cached output object.
((ShapeMetadata) shape.Metadata).OnDisplayed(displayed => cachedOutput.Output = displayed.ChildContent);
} else {
// Found cached output, so simply output it instead of building
// the shape normally.
// This is a dummy shape, the name doesn't matter.
shape = shapeHelper.CachedShape();
// Hook up an event handler to fill the output of this shape with the cached output.
((ShapeMetadata)shape.Metadata).OnDisplaying(displaying => displaying.ChildContent = cachedOutput.Output);
// Replacing the ChildContent of the displaying context will cause the display manager
// to simply use that HTML output and skip template rendering.
}
return shape;
});
}
}
}
使用System.Web;
使用DemoModule.Models;
使用Orchard.Caching;
使用Orchard.ContentManagement.Drivers;
使用Orchard.DisplayManagement.Shapes;
名称空间DemoModule.Drivers{
公共类MyWidgetPartDriver:ContentPartDriver{
专用只读ICacheManager(U cacheManager);
专用只读ISignals\u信号;
公共MyWidgetPartDriver(
ICacheManager缓存管理器,
信号
) {
_cacheManager=cacheManager;
_信号=信号;
}
公共类缓存输出{
公共IHtmlString输出{get;set;}
}
受保护的重写驱动程序结果显示(MyWidgetPart部分、字符串显示类型、动态形状帮助){
返回ContentShape(“Parts\u MyWidget”,()=>{
//缓存键。使用区分输出所需的任何内容构建它。
var cacheKey=/*例如.*/string.Format(“MyWidget-{0}”,part.Id);
//标准Orchard缓存管理器。注意,我们通过引用获取此对象,
//因此,我们可以写入它的字段以保存缓存的HTML输出。
var cachedOutput=\u cacheManager.Get(cacheKey,ctx=>{
//使用所需的任何信号使缓存无效。
_信号。当(/*例如*/“ExpireCache”);
返回新的CachedOutput();
});
动态形状;
if(cachedOutput.Output==null){
//输出尚未缓存,因此我们将正常构建形状
//然后缓存输出。
/*
…做正常的(可能昂贵的)事情(呼叫数据库、呼叫服务等)
要准备形状。。。
*/
//创建形状对象。
shape=shapeHelper.Parts\u MyWidget(/*…*/);
//连接事件处理程序,以便在呈现事件后(可能很昂贵)
//在形状模板中,我们将输出捕获到缓存的输出对象。
((ShapeMetadata)shape.Metadata).OnDisplayed(displayed=>cachedOutput.Output=displayed.ChildContent);
}否则{
//找到缓存输出,因此只需输出它,而不是生成
//形状正常。
//这是一个虚拟形状,名称无关紧要。
shape=shapeHelper.CachedShape();
//连接一个事件处理程序,用缓存的输出填充此形状的输出。
((ShapeMetadata)shape.Metadata).ondisplay(display=>display.ChildContent=cachedOutput.Output);
//替换显示上下文的子内容将导致显示管理器
//只需使用该HTML输出并跳过模板呈现。
}
返回形状;
});
}
}
}
编辑:
请注意,这仅缓存从形状输出生成的HTML。在形状模板中执行的Script.Require()、Capture()和其他副作用等操作将不会播放。这实际上对我有点影响,因为我试图缓存一个需要自己的样式表的模板,但是样式表只会在第一次引入。缓存形状
对象本身不是一个好主意,但是您可以从形状
捕获HTML输出并缓存它
每个Orchard形状
都有一个相应的对象调用