如何缓存RazorEngine中的模板?

Rab*_*bbi 12 razor

当您调用时RazorEngine.Razor.Compile(),编译的模板存储在哪里?

程序重启后是否可用?如果内存不足,会被丢弃吗?

RazorEngineASP.NET(MVC)项目中使用.应用程序重启后,预编译模板是否可用?

将它们存放在HttpContext.Cache?中会更有意义吗?如果我这样做,那么使用Compile绕过内部缓存的不同功能(除了)更有意义吗?有没有办法执行ITemplate并只是传递一个模型?

RazorEngine.Razor.Parse()任何缓存吗?或者每次都重新编译模板?

Mat*_*ott 17

目前,在RazorEngine编译模板后,它们被加载到内存中.这些程序集仅在内存中保留,并且不会超出应用程序的生命周期.

我正在考虑添加支持将这些程序集编译到文件,但这将是未来的版本.

如果您调用Razor.Parse并传入模板的名称,它将尝试

  1. 检查内存中程序集的缓存以查找具有相同名称的程序集.
  2. 无效的模板内容缓存已更改.
  3. 缓存新编译的模板.

  • 仅供参考,这不是当前RazorEngine的工作原理.Profilling显示Razor.Parse导致每次网络呼叫延迟2秒.使用Razor.GetTemplate()将其切换出来; Razor.Run(); 正确地触发了我们的缓存. (3认同)
  • 诀窍是调用Compile()一次,然后多次调用Run(),而不是Parse().Parse()很贵,但Run()很便宜. (2认同)

Ste*_*per 7

我已经将它与2014年1月下旬安装的RazorEngine 3.4.1.0配合使用.

关键是调用昂贵Razor.Compile(content, name)的模板放入缓存,然后调用廉价Razor.Run(name, model)来执行模板.

请记住,阅读模板内容可能很昂贵 - 例如,涉及从磁盘读取 - 因此我的解决方案只获取模板内容一次.这可能对你来说太过缓慢了,所以小心!

这是RenderPartial我在自定义TemplateBase<T>子类中使用的方法.对于同一模板的多次调用,它运行得非常快.

public abstract class SqlTemplate<T>: TemplateBase<T>
{
    public string RenderPartial(string templateName, object model = null)
    {
        // loading a template might be expensive, so be careful to cache content
        if (Razor.Resolve(templateName) == null)
        {
            // we've never seen this template before, so compile it and stick it in cache.
            var templateContent = GetTemplateContent(templateName);
            Razor.Compile(templateContent, templateName);
        }

        // by now, we know we've got a the template cached and ready to run; this is fast
        var renderedContent = Razor.Run(templateName, model); 
        return renderedContent;
    }

    private string GetTemplateContent(string templateName)
    {
        ... your implementation here
    }
}
Run Code Online (Sandbox Code Playgroud)

你还需要告诉Razor使用这个(SqlTempalte<T>)你可以这样做的基类,通过调用RazorEngineConfigurator.Configure();

public static class RazorEngineConfigurator
{
    private static bool configured = false;

    public static void Configure()
    {
        if (configured) 
        {
            return;
        }

        var templateConfig = new TemplateServiceConfiguration
        {
            BaseTemplateType = typeof(SqlTemplate<>), 
            EncodedStringFactory = new RazorEngine.Text.RawStringFactory()
        };

        RazorEngine.Razor.SetTemplateService(new TemplateService(templateConfig));

        configured = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

没有这个SO答案就不可能做到- 为什么不给那个人投票呢?:)


编辑 - 如果您需要以更精细的方式执行缓存,则需要使用RazorEngineTemplateService和使用不同的方法ITemplateResolver.

这是一段入门代码;

    public static RazorEngineTemplateService CreateService(ITemplateResolver resolver, ICollection<string> namespaces)
    {
        Check.IsNotNull(resolver, "resolver");
        var config = new TemplateServiceConfiguration();
        config.BaseTemplateType = typeof(PlainTextTemplate<>);
        config.EncodedStringFactory = new RazorEngine.Text.RawStringFactory();
        config.Resolver = resolver;
        config.Namespaces = new HashSet<string>(namespaces);

        var service = new RazorEngineTemplateService(config);
        return service;
    }
Run Code Online (Sandbox Code Playgroud)

ITemplateResolver将模板名称转换为模板内容,因此您可以实现,例如,CachedFileTemplateResolver从磁盘加载缓存的内容.