1

我有一个带有最新消息列表的小部件,如何仅缓存小部件输出?OutputCache 模块缓存整个页面和匿名用户,但实际上我只需要缓存一个形状输出。这里有什么解决方案?

4

2 回答 2

4

缓存对象本身不是一个好主意Shape,但是您可以从 a 捕获 HTML 输出Shape并缓存它。

每个果园Shape都有一个对应的对象,称为Metadata. 除其他外,此对象包含一些可以在Shape显示时或显示后运行的事件处理程序。通过使用这些事件处理程序,可以缓存Shape第一次调用驱动程序时的输出。然后对于未来对驱动程序的调用,我们可以显示输出的缓存副本,而不是运行驱动程序或模板渲染的昂贵部分。

例子:

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;
            });
        }
    }
}

编辑:请注意,这只缓存从您的形状输出生成的 HTML。您在形状模板中执行的 Script.Require()、Capture() 和其他副作用等内容不会被播放。这实际上让我很生气,因为我试图缓存一个需要自己的样式表的模板,但样式表只会在第一次被引入。

于 2013-11-06T06:30:03.527 回答
1

Orchard 提供了一个名为 CacheManager 的服务,它很棒而且很酷,并且让缓存变得超级简单。文档中提到了它,但它并不是对如何使用它的特别有用的描述(http://docs.orchardproject.net/Documentation/Caching)。查看示例的最佳位置是 Orchard 核心代码和第三方模块,例如 Favicon 和 twitter 小部件(所有人都希望)。

幸运的是,其他好心人已经努力为你搜索 orchards 代码并写了一些关于它的漂亮的小博客文章。LatestTwitter 小部件的开发人员写了一篇简洁的帖子:http ://blog.maartenballiauw.be/post/2011/01/21/Writing-an-Orchard-widget-LatestTwitter.aspx 。NogginBox 的 Richard 也是如此:http ://www.nogginbox.co.uk/blog/orchard-caching-by-time 。当然,Bertrand 也有关于这个主题的有用帖子:http ://weblogs.asp.net/bleroy/archive/2011/02/16/caching-items-in-orchard.aspx

于 2013-10-28T15:43:01.023 回答