12

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

重新启动程序后是否可用?如果内存不足,会被转储吗?

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

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

是否RazorEngine.Razor.Parse()进行任何缓存?还是每次都重新编译模板?

4

2 回答 2

19

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

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

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

  1. 检查内存中程序集的缓存中是否存在同名程序集。
  2. 无效缓存的模板内容已更改。
  3. 缓存新编译的模板。
于 2012-05-22T22:12:56.587 回答
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
    }
}

你还需要告诉 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;
    }
}

如果没有这个 SO 答案,就不可能做到这一点——为什么不也给那个人投票呢?:)


编辑 - 如果您需要以更精细的方式执行缓存,则需要使用不同的方法使用RazorEngineTemplateServiceand 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;
    }

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

于 2014-01-24T10:20:24.300 回答